{"id":"roadmap","relativePath":"roadmap.md","title":"Meta Museum Roadmap","markdown":"# Meta Museum Roadmap\n\nThis is the current, authoritative roadmap. It supersedes [development-roadmap.md](development-roadmap.md) (kept as legacy reference for the pre-Next.js prototype).\n\nThe **north star** is [linked-art/LinkedArtSOTAWebApp.md](linked-art/LinkedArtSOTAWebApp.md). Anywhere this document is silent, the SOTA spec wins for *architecture*; this document wins for *sequencing* — what gets built when, and what is deferred.\nFor provider-expansion and validation slices, [linked-art/LinkedArtModel1.0-Reference.md](linked-art/LinkedArtModel1.0-Reference.md) is a required standards input for implementation and AIDD + TDD.\nThat reference is now the round-based standards ledger for model/API/schema/search/protocol conformance, and roadmap execution assumes tests are mapped to its fixture anchors.\n\n---\n\n## Status (as of July 7, 2026)\n\n<!-- BEGIN:PROJECT_STATS -->\n<!-- Generated by `pnpm docs:stats`; do not edit by hand. -->\n\n| Generated project stats | Current value |\n|---|---|\n| Next.js | `16.2.9` |\n| React | `19.2.4` |\n| App page files | root homepage + `33` non-root page files (`34` total) |\n| API route handlers | `146` `app/api` route handlers |\n<!-- END:PROJECT_STATS -->\n\n- [ ] ⚠️ **Strict 10/10 readiness is not green yet**: `pnpm review:goals:check` still reports `status: external-evidence-required`, `local gate status: passed`, and `strict 10/10 gate status: failed`, but stale deployment proof is no longer the story. GitHub CI is green, and the July 4 production preflight passes `20/20` when the non-secret rotation timestamp and rotated-key list are supplied: Postgres storage, `sslmode=verify-full`, live Neon authentication, active Vercel deployment freshness after secret rotation, auth routes, public-read reachability, validation/reconciliation Render `/health` probes, IIIF tile reachability, DR drill freshness, no production smoke override token, `security.secretRotation`, and `security.secretHistory` all pass. Live probes against `https://www.metamuseum.org` return `200` for `/api/health`, `/api/records`, and `/api/auth/signin`, while `/agents` redirects public users to sign-in. The refreshed production launch-evidence packet passes `8/9`, launch review passes `7/8`, and the remaining launch-review failure is the Era C real-world evidence row. The latest review-goals handoff reports `4` deployment-environment blockers plus `19` real-world-evidence blockers for deployed Render service probes, clean 30-day SLO/uptime windows, ActivityStreams `Delete` type coverage after `3/3` real external consumers and restored `3/3` durable callback rows, partner-confirmed `Update`, paid-pilot entitlement/activation/support-load/KPI proof, retention, and gross-margin evidence; Te Papa first outreach is now recorded, but no reply or paid-pilot proof exists yet. The refreshed 10/10 tracker is [`docs/roadmap-to-10.md`](roadmap-to-10.md).\n- [ ] ⚠️ **Strict real-world lane:** the real-world lane still has `19` blockers, and the highest-leverage remaining ActivityStreams unblocker is real `Delete` evidence. The first reviewed metadata `Update` row is live in production from a real Met object `437133` metadata delta, and MetaHistoryBook re-read it as `metahistorybook-harvester-prod` at `2026-07-05T19:50:30Z` with `totalItems: 1`, real non-synthetic `source.kind: reviewed-update`, conformant projections, and the shared `Q432253` reconciliation. `pnpm providers:coverage:seed` now brings the provider tombstone-watch corpus to all `14/14` source-provider lanes by seeding Harvard from a public object page and Europeana from its read-only Record API status surface, with `0` skipped and `0` failed rows. MoMA is tracked separately as an open-data snapshot provider: `pnpm moma:dataset:diff` compares explicit Artworks snapshots and writes review-required removal candidates without creating ActivityStreams `Delete` readiness. The `Delete` side remains intentionally blocked because the latest provider-aware `pnpm activity:tombstone:scan` run considered `126` stored records at `2026-07-10T01:07:06.186Z`, scanned `68` unique upstream targets across all `14` source providers, skipped `5` unknown/local records, collapsed `53` duplicate Met targets, and found `0` real upstream `404`/`410` tombstones. Next strict step: send a separate `Delete` deploy-note only after a genuine tombstone appears. The same lane still needs the invoice-backed pilot, 30-day SLO/uptime, KPI, retention, and gross-margin proof.\n- [x] ✅ **Latest local verification:** ActivityStreams syndication evidence, provider tombstone-watch evidence, review-goals local gate, and focused review/readiness tests pass for this evidence refresh; the remaining strict blockers are real-world proof, not stale callback, dataset, or local-readiness artifacts. The 10/10 tracker has a drift guard against the latest `artifacts/review-goals/review-goals-latest.json` strict-handoff counts so stale blocker totals are caught in tests.\n- [x] ✅ **B6.1 equivalent-URI reconciliation proof:** exhibition/literature candidates now count Linked Art `equivalent[]` identity hints on works and embedded participants as identifier/participant overlap while preserving full opaque URI evidence. Compact Wikidata, OpenLibrary, and Getty keys are derived only from recognized authority URI/CURIE shapes, and `tests/quality/reconciliation-exhibitions-literature.test.ts` guards arbitrary URI paths from being promoted to authority identifiers.\n- [x] ✅ **Durable callback proof guard:** `pnpm activity:subscriptions:guard` now runs inside `pnpm activity:syndication:evidence`, verifies the three accepted partner callback rows plus their non-placeholder callback proof artifacts, preserves the current zero rejected subscriptions state, and is called explicitly by the nightly Era C evidence workflow. The durable consumer/subscription ledgers and callback proof JSONs are intentionally trackable while the rest of the generated ActivityStreams artifact directory stays ignored.\n- [x] ✅ **Strict handoff public-doc drift guard:** documentation drift tests now compare the latest review-goals strict handoff counts against the README, roadmap, and roadmap-to-10 summaries, so total production-proof blockers and deployment/real-world lane counts cannot quietly diverge after evidence refreshes.\n- [x] ✅ **Deterministic local test gate:** `pnpm test` and `pnpm test:coverage` now pass Node's test runner `--test-concurrency=1` after repeated full-suite runs exposed order-sensitive conformance files that passed in isolation and under the serial quality subset. This preserves the canonical green gate while the route-level conformance suites continue to exercise process-local env/fetch/storage behavior.\n- [x] ✅ **Core stack and runtime**: generated project stats above provide the current Next.js and React pins; TypeScript strict + custom CSS remain the runtime baseline. Latest pilot outreach reply/evidence guard passed focused evidence/outreach/activation/support operator/service/offer/page/storage/docs/exporter checks (`70` tests / `13` suites), final `pnpm test` (`1103` tests / `310` suites), `pnpm lint`, and `pnpm build`; `/pilot` now renders a typed zero-complete activation evidence ledger with the six canonical seven-day pilot milestones, while `src/services/pilot-outreach-events.ts`, `src/services/pilot-activation-events.ts`, `src/services/pilot-support-issues.ts`, and `src/services/pilot-evidence-packet.ts` record sequence-guarded exact-account outreach, ordered exact-tenant activation events, chronology/status/identity/severity/resolution-evidence-guarded support load, explicit blocked/ready pilot packet artifacts, blocker-first Markdown packet summaries, open-blocking-support readiness blockers, and overdue open support-response blockers, `pnpm pilot:outreach`, `pnpm pilot:activation`, `pnpm pilot:support`, and `pnpm pilot:evidence --markdown` let operators append, package, and share real dated evidence without hand-editing JSON, and the runbook forbids marking outreach, activation, support, or packet readiness complete from demo, fixture, smoke evidence, reply claims without prior sent evidence, replies dated before `sentAt`, sent follow-up dates that predate `sentAt`, tenant-mismatched activation evidence, later activation milestones without prior tenant evidence, support response deadlines before `openedAt`, support issue `requester`, `summary`, `openedAt`, or `severity` rewrites, resolved support issue `resolvedAt` or `resolutionSummary` rewrites, support resolutions before `openedAt`, or open support issues carrying resolution evidence. Tenant RBAC evidence still proves signed-in members cannot use sibling active-org cookies to read sibling record lists/details, write records into sibling/default storage, read/review/publish/write sibling wiki draft state, read/review/triage/write sibling annotation queues, read/write sibling AgentTask history, or steer scoped AI/editorial record-read outputs away from their authenticated org; proving signed-in non-members cannot use a cookie-selected org to read or mutate records, annotation, wiki draft, or scoped AI/editorial record-read outputs; and proving signed-in non-admin roles cannot use org administration or support-adjacent routes to list orgs, add memberships, create/revoke invites, or export org audit packets. Gated pilot API routes return stable `429`/`Retry-After` denials before parsing or work execution without changing monthly quota denial semantics. The membership-validated `metamuseum.activeOrgId` cookie drives shared preview, request-storage, and pilot route-gate scope without weakening test override or explicit `?tenantId=...` compatibility precedence. The workspace shell renders sanitized active-org status, org id, accessible-org count, storage scope, membership role, selector, stale-selection warning, and an `/orgs` switch/manage affordance without exposing invite token material. Workspace records, explore, entities, entity detail, artwork detail, graph, and patterns pages derive preview storage from authenticated org session scope when no compatibility `?tenantId=...` is supplied, while explicit tenant preview links still win for controlled pilot URLs. Manual pilot entitlements can bind to authenticated org ids while route usage gates prefer the selected active org for entitlement lookup and post-success counter writes before compatibility tenant headers. `/orgs` can render the operator console while admin-only org routes create/list orgs, memberships, sanitized invites, invite revocation, invite acceptance, form posts, org-scoped audit rows, and org audit export packets while Auth.js org scope continues to resolve from managed org memberships/invites before compatibility env mappings or pilot tenant headers. Wiki draft create/list/detail/review/publish access, live-publish sync-map artifacts, reverse-ETL state, and tenant preview pages remain scoped while unscoped public requests cannot see scoped tenant records or artifacts. Provider facade/direct provider/explorer/Linked Art import writes, public browse reads, records, jobs, AgentTask, annotation, audit, activity route storage, wiki draft storage/access routes, wiki sync-map routes, and tenant-scoped export/DR managed documents remain isolated. The temporary `metagenauto/` AG2 reference repo has been distilled into `docs/agents/ag2-extraction-notes.md` before removal from the app tree.\n- [x] ✅ **Product surface**: generated project stats above provide the current page and API handler counts; the live surface includes 14 provider integrations, ARK resolver, provider facade/readiness/capabilities, standards APIs, ActivityStreams, OpenAPI/docs, worker status API, AI query/chat/evals, org admin/invite APIs, org audit export, `/api/orgs/active` active-org selection, the `/orgs` operator console for org provisioning, memberships, invites, and revocation, `/workers` operator health for projection/publish drain lag, next cron wakeup, effective drain time, and disabled modes, workspace-shell active-org status with selector, stale-selection warning, and switch/manage affordance, persisted AgentTask review history, wiki publish/sync, annotations, public trust, IIIF routes, a larger rotating midnight/navy rain-blue home hero with bright lemon-yellow Meta Museum highlights, top-padded full-color unfiltered contained artwork, a verified Met/CMA/AIC clean-deploy fallback when local image-backed imports are absent, a centered non-overlapping navy artwork info panel, a white hero label, three source-backed real-artwork pathway cards with provider/maker/date/rights/link metadata instead of AI placeholder images, a more readable artwork detail facts panel with metadata-forward desktop proportions and full-width long source fields, a HAL-powered “Related” panel on entity and artwork detail pages for followable Linked Art relation searches, a full-width “Live source network” homepage band that frames the current project as a source-backed workbench with numbered source metrics, provenance, rights/attribution context, citation checks, and editor-gated review signals, a `/projects` product case-study surface with a short “what matters in 90 seconds” evaluator brief, hidden technical proof disclosures, walkthrough video, proof strip, live route links, architecture evidence links, and an honest strict-readiness note, and the `/pilot` Managed Linked Art Launch Pilot offer page with shared primary/footer navigation access, named outreach status ledger, zero-complete activation evidence ledger, and validated operator flows for outreach and activation evidence.\n- [x] ✅ **External evidence ledger**: `/evidence` and `/api/evidence/ledger` now give evaluators a compact public proof surface over partner-confirmed `Update`, durable callback proof, MetaHistoryBook's FAIR/LOUD dataset reuse confirmation, the provider tombstone watch, 30-day SLO/uptime progress, and invoice-backed pilot blockers. `/api/evidence` is a compatibility alias and `/en/evidence` is an explicit locale route for external readers following locale redirects. It deliberately renders `Delete` as pending genuine upstream `404`/`410` evidence rather than treating an empty `type=Delete` feed as a defect to paper over, the production API falls back to public docs when generated artifact JSON is not bundled, and production responses include live probes for the current `Update` feed, Update `linkedArt.id` dereference into `/api/events/...`, intentionally empty `Delete` feed, dataset profile headers, and NDJSON export integrity. The ledger also publishes a tombstone-watch history from retained scan-run artifacts so repeated 14-provider scans are visible over time, not just the latest no-tombstone snapshot. `pnpm evidence:ledger:probe:check` now retains the live ledger result as `artifacts/evidence-ledger/evidence-ledger-probe-latest.json` plus timestamped run artifacts, the nightly Era C workflow captures/uploads those artifacts, and `/readiness` surfaces the latest probe as an operator source.\n- [x] ✅ **Museums Victoria provider slice (2026-07-04)**: added an item-first Museums Victoria Collections API provider with bounded `recordtype=item` search, object fetch, import, `/explore` source toggle, provider facade routes, media-rights preservation, First Peoples/cultural-context review notes, rights-map coverage, and generated pass/fail fixtures. Articles, species, and specimens remain intentionally excluded until separate semantic mapping exists. Provider notes: [docs/providers/museumsvictoria-collections-api.md](providers/museumsvictoria-collections-api.md).\n- [x] ✅ **Portfolio product polish controls**: [`src/services/portfolio-product-polish-controls.ts`](../src/services/portfolio-product-polish-controls.ts) and [`tests/services/portfolio-product-polish-controls.test.ts`](../tests/services/portfolio-product-polish-controls.test.ts) now keep the `/projects` case study, product walkthrough video, standalone overview HTML, public docs freshness metadata, shared navigation, and strict-readiness copy boundary in one executable report.\n- [x] ✅ **Operator readiness page**: `/readiness` now condenses existing ignored readiness artifacts into one editor-gated status view with local-vs-strict claim boundaries, source freshness, blocker rows, and next remediation commands. It also renders the generated acceptance ledger from long-window maintenance, ActivityStreams community-outreach, ActivityStreams partner-pack, paid-pilot buyer-pack, FAIR/LOUD dataset reuse, evidence-ledger live probes, and SOTA KPI artifacts, plus a dataset reuse source card for MetaHistoryBook's external confirmation of dataset discovery, checksum integrity, export pagination, object-level `equivalent[]`, Wikidata reconciliation, and license-scope clarity. The strict readiness audit source card now shows the `strictGateHandoff` blocker, next-action, command, artifact, and requirement counts, while the page also exposes the `review-goals.nextActions[]` strict handoff as an action queue grouped by execution scope with deployment-environment and real-world proof lane totals before row-level commands, so local gates, optional evidence rows, outreach context, repair hints, executable strict actions, and strict production proof remain visibly distinct.\n- [x] ✅ **Operator stale-preflight guard**: `/readiness` now fails production deployment-preflight source rows when the latest artifact is missing current selected secret evidence checks (`security.secretRotation`, `security.secretHistory`), even if the stale artifact summary says `pass`, and adds `pnpm launch:preflight:production` to the next-command list.\n- [x] ✅ **Readiness mismatch guard**: `/readiness` preserves local-gate and strict-gate proof booleans from review-goals artifacts, renders strict production proof as “not proven” whenever external evidence is still required, and downgrades any global strict-gate pass when the five real-world evidence contracts are not independently satisfied.\n- [x] ✅ **Strict evidence loop visibility**: `/readiness` now surfaces the review-goals handoff as three distinct evidence lanes — local refresh, deployment-environment proof, and real-world production proof — with blocker counts, commands, requirements, and artifact targets kept separate so local gate confidence cannot be presented as strict readiness. It also renders five strict external evidence contracts for 30-day SLO/uptime, ActivityStreams adoption, invoice-backed paid pilot, pilot retention, and gross-margin proof; each contract rejects local substitutes, names the source and acceptance-ledger rows it depends on, and remains failed until its own real-world evidence lands. Production launch-packet a11y remediation now points operators at `BASE_URL=https://<deploy-host> pnpm a11y:check` in the deployment-environment lane, so a stale embedded artifact command cannot look like a local-only fix.\n- [x] ✅ **Evidence script ownership**: high-churn launch, review-goals, long-term, ActivityStreams, pilot, continuity, AI-eval, worker, and governance commands now have a typed owner registry plus a regression guard, with the human handoff at [`docs/ops/evidence-script-ownership.md`](ops/evidence-script-ownership.md). The ActivityStreams owner row explicitly covers `pnpm activity:subscriptions:guard` so durable callback verification cannot drift outside the accountable evidence lane. Package-script namespaces now also have owner, preferred-entry-point, and pruning-rule controls so new `namespace:*` command groups cannot appear unclassified.\n- [x] ✅ **Operations risk controls**: [`src/services/operations-risk-controls.ts`](../src/services/operations-risk-controls.ts) and [`tests/services/operations-risk-controls.test.ts`](../tests/services/operations-risk-controls.test.ts) now summarize and regression-check the four recurring operations risks: the large API route surface with first-level route-family owner/review-lane classification, package-script namespace classification plus high-churn script ownership, mixed Vercel/Neon/Render/Redis/Solr/GraphDB topology, and schema/freshness/retention controls for readiness artifacts.\n- [x] ✅ **Turbopack runtime-file warning cleanup**: runtime-only artifact, storage, SHACL, schedule, and queue file reads now use [`src/utils/runtime-fs.ts`](../src/utils/runtime-fs.ts), so `pnpm build` keeps those dynamic paths out of static file tracing and finishes without broad file-pattern warnings.\n- [x] ✅ **Public docs metadata freshness**: `/api/docs/manifest` now reports response `generatedAt` separately from declared source `sourceUpdatedAt` plus `sourceUpdatedDoc` latest-source checksum metadata, keeping Vercel bundle mtimes or response timing from being mistaken for source-document currency.\n- [x] ✅ **OKF / LLM wiki seed**: [docs/knowledge](knowledge/index.md) now starts a project-local Open Knowledge Format-style bundle with a root index, append-only log, source summaries for the OKF announcement and LLM Wiki pattern note, concept pages for OKF, the LLM Wiki pattern, and the Meta Museum knowledge system, plus a maintainer schema that tells agents how to ingest, query, and lint the wiki. `pnpm okf:check` validates that reserved `index.md`/`log.md` files stay separate from typed concept documents with non-empty `type` frontmatter.\n- [x] ✅ **Linked Art HAL reference capture**: [linked-art/api/hal.md](linked-art/api/hal.md) now records the `_links` boundary, CURIE/version/alternate/collection rules, the detailed high-priority relation-search notes captured so far, and the complete 95-name upstream relation inventory extracted from the cloned `linked.art/scripts/hal_links.tsv` mirror. The doc keeps the current implementation boundary explicit: semantic activity/concept/object-part/object-to-work/production-influence/group-formation/custody/encounter/ownership/production/set-creation/work-aboutness/representation/work-creation/work-publication/place-activity/active-place data is preserved; entity-role responses now expose followable usage-indexed named HAL relation links for `la:objectProducedByAgent`, `la:objectOwnedByAgent`, `la:objectCuratedByAgent`, `la:objectMemberOfSet`, `la:objectPartOfObject`, `la:objectCarriesWork`, `la:objectShowsWork`, `la:workAboutAgent`, `la:workRepresentsAgent`, `la:workAboutOrRepresentsAgent`, `la:activityCarriedOutByAgent`, `la:activityUsedObject`, `la:activityTookPlaceAtPlace`, `la:groupFoundedByAgent`, `la:objectEncounteredByAgent`, `la:agentActiveAtPlace`, `la:objectProductionInfluencedByAgent`, `la:objectProductionInfluencedByObject`, `la:objectProductionInfluencedByPlace`, `la:objectProductionInfluencedByWork`, `la:setCreatedByAgent`, `la:conceptInfluencedByObject`, `la:workCreatedByAgent`, and `la:workPublishedByAgent`; `/api/relations` now exposes the supported relation definition catalog with domain/range/search-template metadata; and `/api/relations/{relation}` pages carry relation/current/return-class/conformance/partOf metadata rather than a bare result list. Full relation breadth for work/object/set/place/concept variants beyond the currently indexed subset and other upstream relation families remains next implementation work with failing-first relation tests. The Linked Art inspector also warns when dereferenceable embedded activity/shared-structure IDs omit `_complete: false`.\n- [x] ✅ **HAL relation explorer UI**: entity and artwork detail pages now reuse those followable `la:*` relation links in a visible “Related” panel, exposing produced-object, work-aboutness/representation, owner/curator, object-part, and place-activity searches as clickable `OrderedCollectionPage` API affordances instead of keeping relation-search value hidden in JSON only.\n- [x] ✅ **Linked Art relation-search expansion slices**: `activityCarriedOutByAgent`, `activityUsedObject`, `activityTookPlaceAtPlace`, `groupFoundedByAgent`, `objectEncounteredByAgent`, `agentActiveAtPlace`, `objectCarriesWork`, `objectShowsWork`, `objectProductionInfluencedByAgent`, `objectProductionInfluencedByObject`, `objectProductionInfluencedByPlace`, `objectProductionInfluencedByWork`, `setCreatedByAgent`, `conceptInfluencedByObject`, `workAboutOrRepresentsAgent`, `workCreatedByAgent`, and `workPublishedByAgent` now have registry metadata, sparse POST preservation where needed, entity-index extraction for top-level and embedded activities, formation actors, encounter actors, agent active-place references, physical object `carries`/`shows` object-to-work evidence, production influences, set creation, concept influence, and work aboutness/representation/creation/publication evidence, `/api/relations` discovery, followable entity `_links`, and `OrderedCollectionPage` tests proving Activity/Event, Group, HumanMadeObject, Agent, Place, Set, Type, and Work return-class behavior.\n- [x] ✅ **Linked Art provenance search surface**: `/api/provenance` now provides a provenance-specialized Linked Art Search API page over stored provenance wrappers, with `kind=acquisition`, `kind=custody`, `kind=transfer`, `kind=move`, and `kind=right-acquisition` filters plus optional `object=` filtering. Responses include `provenanceKind`, `conforms_to`, `partOf`, `la:provenanceProfile`, source object summaries, wrapper activities, and matching `part[]` entries so acquisition, custody, indeterminate transfer, movement, and rights-acquisition evidence stays distinct at discovery time. Evidence: [`tests/api/provenance.test.ts`](../tests/api/provenance.test.ts).\n- [x] ✅ **HAL entity envelope upgrade**: shared entity/record HAL responses now emit `self`, a templated Linked Art `la` CURIE, `la:activityFeed`, and link-object `la:apiVersion`/`la:modelVersion` entries with `href` and `name`, replacing the older string-only version metadata while keeping HAL out of the semantic graph payload.\n- [x] ✅ **FAIR/LOUD dataset publication surface**: `/api/datasets` now publishes a machine-readable DCAT/DataCite/VoID-style JSON-LD dataset profile with dataset id, version, checksum, license, update cadence, distributions, and canonical identifier policy. `/api/datasets/exports/records?format=jsonld|ndjson` provides downloadable versioned record envelopes with per-record rights/provenance packaging and object-level `equivalent[]` links projected from stored equivalents, provider URLs, public object pages, and Wikidata entity URLs; `/api/providers/capabilities` advertises those dataset distributions for follow-your-nose discovery; dataset responses expose id/version/distribution/checksum/license headers for integrity checks without body parsing; `/api/datasets` states that CC BY 4.0 governs export packaging/metadata while per-record rights govern object/content/media reuse; `/datasets` links the machine-readable profile and exports; and [linked-art/canonical-identifier-policy.md](linked-art/canonical-identifier-policy.md) documents persistence, redirects, content negotiation, ARK/DOI strategy, reconciliation equivalents, and license scope. MetaHistoryBook re-read dataset version `2026.07.06+sha256.43eb7f0049c9` and confirmed `53/54` non-empty `record.equivalent[]` rows, `47/54` Wikidata rows, checksum validity, pagination/discovery, and license-scope clarity, converting the dataset reuse package from self-verified to partner-verified evidence. This improves reuse packaging without treating the remaining real-world Delete or 30-day SLO/uptime evidence as complete.\n- [x] ✅ **Performance scale controls**: [`src/services/performance-scalability-controls.ts`](../src/services/performance-scalability-controls.ts) and [`tests/services/performance-scalability-controls.test.ts`](../tests/services/performance-scalability-controls.test.ts) now exercise cold-record SLO miss/depth behavior, Solr/GraphDB projection enablement thresholds, bounded cron backlog escalation, and provider cache/rate-limit/validation-drift safeguards.\n- [x] ✅ **Calendar-auditable long-window evidence**: `pnpm longterm:evidence` and `pnpm longterm:evidence:maintenance` now include observed and missing UTC days for SLO and public-read uptime windows, and the maintenance Markdown names missing days so 30-day readiness cannot be inferred from clustered or opaque sample totals. The maintenance report also carries SLO trend-intake diagnostics, grouped repair-queue rows for retained SLO metric failures and public-read uptime path failures, row-level and per-failed-sample age-out dates, acceptance rows for SLO sample depth, SLO failure-free status, uptime observation depth, uptime availability, ActivityStreams consumer depth, activity-type coverage, and strict long-term packet refresh; `/readiness` shows the repair-queue count without treating it as proof. The latest July 6 long-window maintenance artifact has `20/30` retained deployed SLO samples across `7/30` observed UTC days, `13/30` passing SLO samples across `6/30` passing days, `7` failed/incomplete retained SLO rows, and SLO trend intake of `23` raw timestamped rows with `20` inside the report window and `3` older than the window. Public-read uptime has `117` retained probe snapshots with `0.9744` availability across `9/30` observed days, and the last retained failed SLO/uptime sample ages out by `2026-07-28T20:28:03.851Z`; daily passing-depth evidence is ready no earlier than `2026-07-29T09:15:00.000Z` if every future sample passes and adoption evidence lands. Review-goals now derives long-term blocker detail from retained sample counts, failed/incomplete sample counts, distinct-day coverage, uptime availability, and missing ActivityStreams activity types, so the strict handoff cannot hide behind aggregate sample totals.\n- [x] ✅ **Scheduled public-read probe contract**: `.github/workflows/era-c-exit-gate-evidence.yml` now defaults `METAMUSEUM_PUBLIC_READ_BASE_URL` to `https://www.metamuseum.org` and runs `pnpm era-c:exit-gate:public`, so nightly Era C packets require production probe-backed uptime instead of inheriting local or variable-only telemetry.\n- [x] ✅ **CI readiness workflow repair**: GitHub build/smoke jobs now set a CI-only dummy `AUTH_SECRET` so the production auth-secret throw remains intact while clean runners can compile and start Next, env-loader tests isolate inherited CI secrets before checking local file assignment, the standalone public-trust smoke filter watches auth/workflow changes, review-goals tests assert evidence-loop invariants from generated reports and tolerate both local-present and clean-runner-missing artifact blocker shapes, ActivityStreams adoption controls keep ignored generated partner-pack outputs as handoff targets without requiring them to exist in a clean checkout, the a11y smoke treats expected `/agents` and `/automation` Auth.js redirects as protected-route passes, and the Era C evidence workflow force-adds only its explicit rolling-evidence allowlist.\n- [x] ✅ **SOTA §26 KPI export path**: `pnpm monitoring:kpi-evidence` writes current-environment `monitoring/kpi-evidence.json` from record-enrichment and reconciliation decision counts, `pnpm monitoring:kpi-evidence:production` now loads repo env files before requiring Postgres storage and production source labels, real reviewed/accepted auto-link counts must be supplied together, and reviewed precision now also requires `--reviewed-precision-source` naming production review evidence before it enters the KPI snapshot. The KPI enrichment counter now counts unique recognized authority references rather than authority source families; the July 4 local export writes `1/5` ready acceptance rows, `0/4` ready production capture rows, `2` KPI metric blockers, and `diagnostics.handoffSummary.status: needs-production-evidence`; the record denominator is present, local enrichment is `52/57` (`0.9123`) against the `46/57` threshold, reconciliation candidates remain `0`, and reviewed precision still needs real reviewed/accepted auto-link counts plus a production review source. The handoff now separates strict source-shape work from metric work: `nextCommand` asks for the production KPI export, while `nextMetricCommand` points directly at production reconciliation distribution capture with `--auto-link`, `--weekly-digest`, `--human-review`, and `--drop-candidate`; `/readiness` shows both the metric-specific command and the required metric evidence text in the SOTA KPI source card. The export includes acceptance rows for production record export, enrichment denominator, production reconciliation export, reviewed precision counts/source, and strict Era C refresh readiness, plus KPI diagnostics with metric previews, `diagnostics.evidenceNeeds`, a capped `sampleRecordGaps[]` enrichment repair sample for under-authoritied record IDs, each sample's existing recognized authority URIs and suggested Linked Art fields, production-only `diagnostics.capturePlan` rows, and `diagnostics.handoffSummary` so the source-shape and metric next evidence are visible without inferring them from the failed gate.\n- [x] ✅ **ActivityStreams onboarding ledger**: `pnpm activity:partner-pack` now gives each requested consumer copy-ready outreach text, a partner response template, an evidence checklist, and structured acceptance rows for declared-feed-read, activity-type coverage, durable-subscription, callback-verification, and strict-gate-refresh proof. The placeholder pack keeps `consumerIds: []` and `pending-consumer-id` rows, so outreach scaffolding cannot count as strict adoption evidence. `pnpm activity:syndication:evidence` emits `consumerOnboarding.rows` with feed-read, durable-subscription, callback-verification, blocker, next-action, and evidence-ref fields so real external adoption can be tracked consumer by consumer.\n- [x] ✅ **Linked Art-native activity stream lift (2026-07-04, activity-class/provenance coverage lifted 2026-07-06)**: `/api/activity` now embeds a `linkedArt` JSON-LD projection on every ActivityStreams item, extracts semantic record events from `produced_by`, `created_by`, `modified_by`, `destroyed_by`, `removed_by`, `encountered_by`, `formed_by`, `dissolved_by`, `born`, `died`, title/custody transfer, and `used_for` properties, emits conservative `record-backfill` `Create` activities for otherwise uncovered stored records, supports `type`, `source`, `provider`, `object`, `since`, `until`, and cursor sync filters, keeps offset `nextPage` compatibility, defaults absent `limit` to a 25-item page, falls back to offset `next` links instead of emitting invalid cursors, and exposes object-scoped feeds at `/api/activity/object/{encodedObjectId}`. Linked Art `Destruction` and `Dissolution` stay semantic `Update` feed rows, so the strict ActivityStreams `Delete` lane remains reserved for real upstream `404`/`410` tombstones; dereferenceable activity IDs preserve source-supplied `_complete: false`; `Set` records emit `Creation`/`created` rows instead of physical `Production` rows, while record detail keeps `member_of` links on member records instead of inventing inverse `member[]` lists on the Set; `Birth`/`Death` projections suppress disallowed `carried_out_by` and `used_specific_object` fields; and provenance wrapper activities preserve names, classifications, descriptions, relative `before`/`after` ordering, and bundled `part[]` entries such as `Encounter`, `Acquisition`, indeterminate `Transfer`, `RightAcquisition`, `Move`, and `Payment`, including find/rediscovery encounters, explicit rights establishment/invalidation, percentage ownership shares, copyright rights, unknown-transfer evidence without title/custody assertions, multiple-owner, agent-carried acquisition, exchange, custody-transfer loans, movement origin/destination places, theft/loss custody changes, commission/service payment details, auction event classifications, auction-of-lot identifiers, lot `Set` `used_specific_object` values, `part_of` auction links, provenance purchases `caused_by` the lot auction, exhibition venue/organizer metadata, exhibition-object `Set` links, concept influence, and travelling-exhibition `part_of` links. After MetaHistoryBook partner feedback, `/api/activity/collection` and `/api/activity/page/{page}` now add a first IIIF Change Discovery-compatible walk-back surface with a mandatory collection `last` link, fixed ascending `OrderedCollectionPage` resources, thin default activities, valid UTC page `endTime` values, dereferenceable MetaMuseum `object.id` URLs for record-backed rows, opt-in `embed=linked-art`, omitted absent `prev`/`next` links, `object.equivalent[]` reconciliation hooks synthesized from stored equivalents, provider URLs, and object Wikidata URLs, and declared-consumer telemetry for walk-back harvesters while preserving the cursor API as an extension. The partner test-ID rerun structurally passed; the first production-ID run then passed ordering, real timestamps, and dedupe but exposed the source-equivalent gap, so record detail responses now project both bare and HTTP stored IDs as canonical `/api/records/{encodedSourceRecordId}` URLs with `_links.self.href` alignment and source/Wikidata equivalents for strict Linked Art consumers. The July 5 `metahistorybook-harvester-prod` rerun passed all four validation points and is filed as first production-grade external-consumer harvest evidence; Daily's `daily-metahistorybook-prod` app read is filed as a second distinct product consumer and its callback is verified as the first durable subscription row; Wikidata Explorer's `wikidataexplorer-metamuseum-prod` walk-back read is filed as the third distinct external consumer with `53/53` Met `Create` activities and `47/53` QID mappings, and its callback is now verified by a real Met `Create` POST returning `202` plus a GET ledger showing QID `Q29385853`. The adoption matrix and partner onboarding pack now require a broad read plus explicit `type=Create`, `type=Update`, and `type=Delete` reads for each partner ID, keeping future partner evidence aligned with the strict activity-type coverage gate. Reviewed record metadata now emits real `reviewed-update` rows, with Met object `437133` live in production and partner-confirmed by MetaHistoryBook at `2026-07-05T19:50:30Z`; `pnpm activity:tombstone:scan` keeps a latest/run artifact for real upstream `404`/`410` monitoring and `pnpm activity:tombstone:evidence` still creates deletion rows only from real upstream `404`/`410` evidence refs. MetaHistoryBook signed callback proof is accepted with a real production `Create` Activity POST returning `204`, bringing durable callback evidence to `3/3`; strict proof now needs real `Delete` feed-read coverage. `Refresh` handling, stronger delivery guarantees, and real `Delete` observations remain follow-up compatibility/adoption work. Profile doc: [linked-art/activity-stream-profile.md](linked-art/activity-stream-profile.md). Evidence: `tests/api/activity.test.ts`, `tests/api/activity-as2.test.ts`, `tests/api/records/by-id.test.ts`, [linked-art/wikidataexplorer-consumer-evidence.md](linked-art/wikidataexplorer-consumer-evidence.md).\n- [x] ✅ **Linked Art conservation activity proof (2026-07-06)**: `/api/activity` now treats object-level `attributed_by` condition assessments as semantic `AttributeAssignment` `Update` rows, preserving `assigned_property`, `assigned` condition types, descriptions, timespan, actors, and conservation-project `part_of` links separately from `modified_by` conservation `Modification` rows with technique and intervention metadata. Evidence: `src/services/activity-feed.ts`, `tests/api/activity.test.ts`, [linked-art/activity-stream-profile.md](linked-art/activity-stream-profile.md).\n- [x] ✅ **Linked Art actor identity proof (2026-07-06)**: `/api/records/{id}` now has regression coverage for rich `Person` and `Group` records from the People/Organizations pattern: name parts, authority `equivalent[]`, group membership, `contact_point` addresses/phone/email, residence `Place`, birth/death, formation, professional `carried_out` activity, burial `participated_in`, biography statements, and typed nationality/gender/occupation classifications stay as first-class Linked Art structures. Evidence: `tests/api/records/by-id.test.ts`.\n- [x] ✅ **Linked Art place identity proof (2026-07-06)**: `/api/records/{id}` now has regression coverage for the Places pattern: Place classifications, names, descriptions, `part_of` spatial hierarchy, authority `equivalent[]`, WKT `defined_by` geometry, approximate place nesting, and `HumanMadeObject.current_location` references to Places stay distinct so buildings/immovable objects are not coerced into Place records. Evidence: `tests/api/records/by-id.test.ts`.\n- [x] ✅ **Linked Art concept identity proof (2026-07-06)**: `/api/records/{id}` and `/api/concepts/{id}` now have regression coverage for the Concepts pattern: `Type`, `Material`, `Language`, `Currency`, and `MeasurementUnit` remain accepted concept classes; local concept records preserve primary names, AAT `equivalent[]`, `classified_as` meta-types, `broader` hierarchy, concept-scheme `member_of` Sets, coordinated concept `created_by.influenced_by`, and concept references with embedded equivalents without collapsing hierarchy, classification, and grouping. Evidence: `tests/api/records/by-id.test.ts`, `tests/api/entity-roles.test.ts`.\n- [x] ✅ **Linked Art vocabulary-term proof (2026-07-06)**: `/api/records/{id}` now has regression coverage for the vocabulary-term rule that classification terms may cite required/recommended/optional vocabulary URIs directly in `classified_as.id` or through an intermediary local term with the authority URI in `equivalent[]`. The fixture preserves both shapes exactly, so consumers can compare across institutions without Meta Museum flattening local terms or discarding Getty/AAT reconciliation anchors. Evidence: `tests/api/records/by-id.test.ts`.\n- [x] ✅ **Linked Art required-term proof (2026-07-06)**: `/api/records/{id}` now has regression coverage for the full Required Terms family when those concepts are modeled: primary/display/sort names, sort values, statement/type-of-work/style/shape/nationality/occupation/color meta-types, exhibition/provenance/professional/publication/promise activities, and collection-item/artwork flags all preserve the canonical full Getty AAT URIs instead of local substitutes. Evidence: `tests/api/records/by-id.test.ts`.\n- [x] ✅ **Linked Art recommended-term proof (2026-07-06)**: `/api/records/{id}` now has regression coverage for recommended vocabulary families as interoperability preferences rather than hard conformance failures: alternate/person-name parts, accession/local/system/call identifiers, statement categories with the Statement meta-type, object/place/group/digital/set/dimension classifications, language/unit/material/currency instances, nationality and occupation refinements with their meta-types, and shape terms with the Shape meta-type all preserve full Getty AAT URIs when modeled. Evidence: `tests/api/records/by-id.test.ts`.\n- [x] ✅ **Linked Art optional-term proof (2026-07-06)**: `/api/records/{id}` now has regression coverage for optional vocabulary families as mapping aids rather than requirements: translated titles, subtitles, aliases, pseudonyms, auction/ISBN/ISSN/DOI/stock identifiers, email/street/phone/fax contact points, optional statement and document classifications, optional place/group/object/object-part categories, and diameter/length/thickness dimensions all preserve full Getty AAT URIs when present. Evidence: `tests/api/records/by-id.test.ts`.\n- [x] ✅ **Linked Art textual document proof (2026-07-06)**: `/api/records/{id}` now has regression coverage for the Textual Documents pattern: physical book `HumanMadeObject` carriers preserve `carries -> LinguisticObject` text links, textual content preserves monograph/chapter type classifications, primary and system identifiers, language, `content`, authorship `Creation`, publishing `Activity`, object `about` references, abstract-work `part_of` links, pagination statements, computable page-count dimensions, and `digitally_carried_by -> DigitalObject` web-page carriers without collapsing copy, text, and digital surrogate layers. Evidence: `tests/api/records/by-id.test.ts`.\n- [x] ✅ **Linked Art archival hierarchy proof (2026-07-06)**: `/api/records/{id}` now has regression coverage for the Archival Hierarchies pattern: archive, archival grouping, and archival sub-grouping `Set` records preserve conceptual `member_of` hierarchy; archival `HumanMadeObject` letters and `DigitalObject` scans preserve their own `member_of` links; archival Sets use `members_contained_by` to align conceptual groups with physical boxes; item records use `held_or_supported_by` for actual physical containment; and `members_exemplified_by` preserves collective description without inventing inverse `member[]` lists. Evidence: `tests/api/records/by-id.test.ts`.\n- [x] ✅ **Linked Art specific assertion proof (2026-07-06)**: `/api/records/{id}` now has regression coverage for the Specific Assertions pattern: `AttributeAssignment` records preserve `assigned_property`, `assigned`, timespan, source/citation `used_specific_object`, context `caused_by`, uncertain production assignment details, embedded `Identifier`/`Name` `assigned_by` provenance, AI statement creation technique/tool metadata, statement-level rights, and generic related-entity display labels without replacing current canonical values. Evidence: `tests/api/records/by-id.test.ts`.\n- [x] ✅ **Linked Art profile-boundary proof (2026-07-06)**: `/api/records/{id}` now has regression coverage for the Profile design principle itself: baseline JSON-LD fields stay simple and predictable, including context, type, names, classifications, descriptions, equivalents, representations, and current production, while optional complexity is preserved as explicit `AttributeAssignment` expansion evidence with `assigned_property`, `assigned`, timespan, source, and review context. The fixture also keeps `_complete: false` and proves historical assertions do not overwrite current profile values. Evidence: `tests/api/records/by-id.test.ts`.\n- [x] ✅ **Linked Art class-analysis proof (2026-07-06)**: `/api/records/{id}` now has regression coverage for the Class Analysis guidance: public records use practical Linked Art classes such as `HumanMadeObject`, `LinguisticObject`, `VisualItem`, `DigitalObject`, `Name`, `Identifier`, `Set`, `Dimension`, `MeasurementUnit`, `Material`, `Right`, and `Group`, with collection/document/image/identifier specificity carried by `classified_as` terms where needed instead of raw CIDOC-CRM utility classes. A traversal assertion rejects leaked `E##` class names in the returned record graph. Evidence: `tests/api/records/by-id.test.ts`.\n- [x] ✅ **Linked Art API reference docs section (2026-07-06)**: [linked-art/api/index.md](linked-art/api/index.md) now anchors a local Linked Art API 1.0 reference section for implementers and agents, with CC BY attribution, source URLs, endpoint summaries, field checklists, incoming relationship notes, Meta Museum coverage notes, and test ideas. The captured core endpoint notes cover [Abstract Works](linked-art/api/abstract-works.md), [Concepts](linked-art/api/concepts.md), [Digital Objects](linked-art/api/digital-objects.md), [Events](linked-art/api/events.md), [Groups](linked-art/api/groups.md), [People](linked-art/api/people.md), [Physical Objects](linked-art/api/physical-objects.md), [Places](linked-art/api/places.md), [Provenance Activities](linked-art/api/provenance-activities.md), [Sets](linked-art/api/sets.md), [Textual Works](linked-art/api/textual-works.md), and [Visual Works](linked-art/api/visual-works.md); [JSON Schemas](linked-art/api/json-schemas.md) records the official endpoint schema catalog, Abstract Work required fields, and no-additional-properties validation target; [Abstract Work Schema](linked-art/api/schema-abstract-work.md) records expanded `abstract.json` constraints for `PropositionalObject`, permitted top-level fields, embedded names/references/rights/visual/text structures, conceptual parent links, and `created_by` activity shape; [Concept Schema](linked-art/api/schema-concept.md) records expanded `concept.json` constraints for `crm:E55_Type`, concept subclasses, embedded statements/representations, `created_by` activity shape, and `broader` hierarchy; [Digital Object Schema](linked-art/api/schema-digital-object.md) records expanded `digital.json` constraints for `dig:D1_Digital_Object`, access points, media formats, conformance, digital services, carried/shown content, and `used_for`/`created_by` activity evidence; [Event Schema](linked-art/api/schema-event.md) records expanded `event.json` constraints for `Period`/`Event`/`Activity`, timespans, places, temporal ordering, causation, actor responsibility, participants, techniques, and `part_of` references; [Group Schema](linked-art/api/schema-group.md) records expanded `group.json` constraints for `crm:E74_Group`, group membership, performed/participated activities, contact points, residences, formation, and dissolution; [Person Schema](linked-art/api/schema-person.md) records expanded `person.json` constraints for `crm:E21_Person`, group membership, performed/participated activities, contact points, residences, birth, and death; [Physical Object Schema](linked-art/api/schema-physical-object.md) records expanded `object.json` constraints for `crm:E22_Human-Made_Object`, current ownership/custody/location, materials, parts, carrier/content/surrogate relationships, lifecycle activities, and provenance activities; [Shared Structures](linked-art/api/shared-structures.md) records the embedded data-structure families, inherited-context behavior, and `_complete: false` dereference rule; [Shared Activities](linked-art/api/shared-activities.md) records embedded activity classes, incoming relationship names, Birth/Death constraints, and activity `_complete: false` URI behavior; [Shared Digital Links](linked-art/api/shared-digital-links.md) records nested work/digital-object links, `access_point`, service, format, and `conforms_to` behavior; [Shared Dimensions](linked-art/api/shared-dimensions.md) records `Dimension` value/unit/type, uncertainty bounds, duration use, and `assigned_by` measurement evidence; [Shared Concept References](linked-art/api/shared-concept-references.md) records allowed concept classes, notation, equivalent links, and concept meta-classification; [Shared Identifiers](linked-art/api/shared-identifiers.md) records `Identifier` content, classification, notes, contact points, and assignment provenance; [Shared Monetary Amounts](linked-art/api/shared-monetary-amounts.md) records `MonetaryAmount` value/currency/classification, uncertainty bounds, notes, `paid_amount`, and auction-lot dimension usage; [Shared Names](linked-art/api/shared-names.md) records `Name` content, language tagging, nested parts, notes, and assignment provenance; [Shared Rights](linked-art/api/shared-rights.md) records `Right` structures, license/right classifications, rights holders, statements, and `subject_to` usage; [Shared References](linked-art/api/shared-references.md) records compact references, `equivalent`, `notation`, and the no-`_complete` reference rule; [Shared Statements](linked-art/api/shared-statements.md) records embedded `LinguisticObject` content, language, labels, format, rights, creation evidence, and nested statements; [Shared TimeSpans](linked-art/api/shared-timespans.md) records fuzzy boundary dates, duration dimensions, notes, and minimum content requirements; [Shared Relationships](linked-art/api/shared-relationships.md) records `AttributeAssignment` relationship assertions, `assigned`, `assigned_property`, assignment provenance, and arbitrary related-entity links. `/api/docs/manifest` plus `/api/docs/content` have regression coverage proving the section is discoverable through the public docs surfaces. Evidence: `tests/utils/docs.test.ts`, `tests/api/docs.test.ts`.\n- [x] ✅ **Endpoint-family schema enforcement slice**: local Linked Art schema-profile validation now rejects unexpected top-level fields against endpoint-family allowlists for implemented families while permitting documented Meta Museum response metadata (`_links`, `schemaVersion`, `_source`), and a vendored official Linked Art schema JSON executor now checks the same aggregate endpoint-family fixtures for required fields, allowed fields, and `type` const/enum rules. Physical Object, Digital Object, Person, Group, Place, Concept subclasses (`Type`, `Material`, `Language`, `Currency`, `MeasurementUnit`), Event/Activity, Provenance Activity, Set, Textual Work, Visual Work, and Abstract Work pass/extra-field fail fixtures prove no-additional-properties behavior with local and official schema evidence. Recursive checks now cover endpoint-local Provenance Activity `part[]` structures and shared `core.json` structures, including nested Acquisition extra-field rejection, required `transferred_title_of` enforcement, embedded Name extra-field rejection, and required Name `content` enforcement. Evidence: [`tests/quality/validation-architecture-depth.test.ts`](../tests/quality/validation-architecture-depth.test.ts).\n- [x] ✅ **Linked Art graph partition planner**: `src/utils/linked-art-partitioner.ts` now turns arbitrarily shaped but valid Linked Art graph input into discrete endpoint-family documents with first-class endpoint nodes emitted separately, compact references across document boundaries, owned embedded activity/shared structures preserved, `_complete: false` projected onto dereferenceable embedded summaries, recursion bounds for object parts, archival/set hierarchy, concept `broader`/`member_of`, and provenance `part[]` graphs, richer duplicate-node selection, and optional official schema validation on generated partitions. `/api/events/{id}` now uses the planner for ActivityStreams `linkedArt.id` dereferences, including activity subclasses such as `Production`, so event dereference responses keep object/agent relationships partition-bounded instead of recursively embedding record graphs. `/api/objects/{id}` now uses the planner for stored physical object records, bounding object `part` recursion while keeping owned lifecycle summaries such as `produced_by` embedded and their actor/place relationships compact. `/api/sets/{id}` and `/api/concepts/{id}` now use the same planner for stored Set and Concept hierarchy records, bounding `member`, `member_of`, and `broader` recursion while preserving the existing entity-index fallback for nested-only referenced sets/concepts. `/api/records/{id}` now runs record-detail serialization through the planner after canonical MetaMuseum id/equivalent projection, then adopts only recursive/root-activity planner fields so `_links.self`, `_source`, source equivalents, and rich record-detail embeddings stay stable. Evidence: [`tests/utils/linked-art-partitioner.test.ts`](../tests/utils/linked-art-partitioner.test.ts), [`tests/api/activity.test.ts`](../tests/api/activity.test.ts), [`tests/api/entity-roles.test.ts`](../tests/api/entity-roles.test.ts), [`tests/api/records/by-id.test.ts`](../tests/api/records/by-id.test.ts), [linked-art/partitioning.md](linked-art/partitioning.md).\n- [x] ✅ **Linked Art embedded completeness projection slice**: `_complete: false` is now emitted automatically for partial dereferenceable embedded shared structures and activity nodes during record normalization and semantic ActivityStreams `linkedArt` projection, while compact references such as `equivalent`, `member_of`, and actor references remain reference-only without `_complete`. Evidence: [`tests/utils/linked-art.test.ts`](../tests/utils/linked-art.test.ts), [`tests/api/activity.test.ts`](../tests/api/activity.test.ts).\n- [x] ✅ **Linked Art API design-principles reference (2026-07-06)**: [Design Principles](linked-art/api/design-principles.md) records the IIIF-derived API rules for shared use cases, internationalization, simplicity, REST/cacheability, JSON-LD, standards alignment, extensibility, networked retrieval, right-layer problem solving, one-direction relationship assertions, embedding, and opaque URI handling. Evidence: `tests/utils/docs.test.ts`, `tests/api/docs.test.ts`.\n- [x] ✅ **Linked Art API JSON-LD considerations reference (2026-07-06)**: [JSON-LD Considerations](linked-art/api/json-ld-considerations.md) records the canonical Linked Art context, profile media type, case-sensitive terms, `id`/`type` aliases, always-array property discipline, scoped context naming, plain-JSON usability, and RDF compatibility checks for records, exports, and embedded `linkedArt` projections. Evidence: `tests/utils/docs.test.ts`, `tests/api/docs.test.ts`.\n- [x] ✅ **Linked Art API protocol reference (2026-07-06)**: [Protocol](linked-art/api/protocol.md) records the HTTP(S) retrieval contract, required `GET`/`OPTIONS`, optional non-required `HEAD`, Linked Art JSON-LD content negotiation, wildcard CORS, future-version profile URI strategy, persistent URI practice, preferred endpoint names, and opaque URI handling. Evidence: `tests/utils/docs.test.ts`, `tests/api/docs.test.ts`.\n- [x] ✅ **Linked Art API Search and Discovery captures (2026-07-07)**: [Search](linked-art/api/search.md) now records the HAL-driven inverse-discovery pattern, official `OrderedCollectionPage`/embedded `OrderedCollection` shape, `orderedItems`, `next`/`prev`, `startIndex`, and the current Meta Museum refinement target for normalizing local `nextPage`/`prevPage` compatibility fields toward official Search API pagination. [Discovery](linked-art/api/discovery.md) now records HTML and HTTP `describedby` signposting, the exactly-one Linked Art record link rule, FAIR Signposting alignment, IIIF Change Discovery harvesting, Linked Art record-types context usage, and the current route-level refinement target for `Link: rel=\"describedby\"` headers. Evidence: `tests/utils/docs.test.ts`, `tests/api/docs.test.ts`, `tests/quality/data-discovery-signposting.test.ts`, `tests/quality/hal-search-relations-conformance.test.ts`.\n- [x] ✅ **Linked Art canonical Search API pagination refinement (2026-07-07)**: `/api/search` and `/api/relations/{relation}` now emit official `next`/`prev` `OrderedCollectionPage` link objects, `startIndex`, and `partOf.first`/`partOf.last` while preserving existing `nextPage`/`prevPage` compatibility fields. The relation fixture now proves a real next-page boundary with `objectOwnedByAgent&limit=1`, and the shared HAL/search conformance helper checks official link-object shape without forcing every provider-specific legacy search route to migrate at once. Evidence: `tests/api/search.test.ts`, `tests/api/hal-relations.test.ts`, `tests/quality/hal-search-relations-conformance.test.ts`.\n- [x] ✅ **Linked Art code-and-tools reference (2026-07-06)**: [Code And Tools](linked-art/api/code-and-tools.md) records implementation libraries, platforms, documentation/modeling aids, validators, visualization tools, and data-cleaning resources including Crom, LinkedArt.js, Linked.Art.Net, LUX, Arches, Ogee, Zellij, the Linked Art JSON Validator, Simple Dynamic Modelling, Mermaid, and OpenRefine. Evidence: `tests/utils/docs.test.ts`, `tests/api/docs.test.ts`.\n- [x] ✅ **Linked Art bibliography reference (2026-07-06)**: [Bibliography](linked-art/api/bibliography.md) records scholarly and technical sources for Linked Art, LOUD, provenance, semantic annotation, image archives, community practice, and cross-collection discovery, with version-context guidance for using 2024-2025 sources for current claims and older entries for lineage/history. Evidence: `tests/utils/docs.test.ts`, `tests/api/docs.test.ts`.\n- [x] ✅ **Linked Art CDWA mapping reference (2026-07-06)**: [CDWA Mapping](linked-art/api/cdwa-mapping.md) records the Getty CDWA-to-Linked-Art crosswalk for object, title, creation, measurement, materials, statement, activity, provenance, exhibition, visual documentation, textual reference, person/group, place, and concept authority fields, including explicit non-mappings for meta-metadata, Phase-like facts, and unsupported source fields. Evidence: `tests/utils/docs.test.ts`, `tests/api/docs.test.ts`.\n- [x] ✅ **Linked Art Schema.org mapping reference (2026-07-06)**: [Schema.org Mapping](linked-art/api/schema-org-mapping.md) records derivative structured-data projection rules from canonical Linked Art into Schema.org for shared properties, people, organizations, places, concepts, human-made objects, digital objects, visual/textual works, events, and sets while keeping Linked Art as the source of truth. Evidence: `tests/utils/docs.test.ts`, `tests/api/docs.test.ts`.\n- [x] ✅ **Linked Art Place schema reference (2026-07-06)**: [Place Schema](linked-art/api/schema-place.md) records expanded `place.json` constraints for `crm:E53_Place`, required identity fields, no-additional-properties validation, `defined_by` WKT/GeoJSON geometry, `part_of` spatial hierarchy, and incoming object/activity/actor place references. Evidence: `tests/utils/docs.test.ts`, `tests/api/docs.test.ts`.\n- [x] ✅ **Linked Art Provenance Activity schema reference (2026-07-06)**: [Provenance Activity Schema](linked-art/api/schema-provenance-activity.md) records expanded `provenance.json` constraints for `crm:E7_Activity`, required identity fields, required provenance `classified_as`, no-additional-properties validation, temporal/activity context, and `part[]` evidence for acquisition, custody transfer, payment, encounter, movement, rights acquisition, and generic classified provenance activities. Evidence: `tests/utils/docs.test.ts`, `tests/api/docs.test.ts`.\n- [x] ✅ **Linked Art Set schema reference (2026-07-06)**: [Set Schema](linked-art/api/schema-set.md) records expanded `set.json` constraints for `la:Set`, required identity fields, no-additional-properties validation, parent set hierarchy, physical member containers, exemplar member templates, topics, dimensions, and `used_for`/`created_by` activity evidence. Evidence: `tests/utils/docs.test.ts`, `tests/api/docs.test.ts`.\n- [x] ✅ **Linked Art Textual Work schema reference (2026-07-06)**: [Textual Work Schema](linked-art/api/schema-textual-work.md) records expanded `text.json` constraints for `crm:E33_Linguistic_Object`, required identity fields, no-additional-properties validation, language, content, format, rights, aboutness, part relationships, and creation/use activity evidence while preserving carrier boundaries. Evidence: `tests/utils/docs.test.ts`, `tests/api/docs.test.ts`.\n- [x] ✅ **Linked Art Visual Work schema reference (2026-07-06)**: [Visual Work Schema](linked-art/api/schema-visual-work.md) records expanded `image.json` constraints for `crm:E36_Visual_Item`, required identity fields, no-additional-properties validation, rights, dimensions, aboutness, represented entities, represented entity types, part/conceptual relationships, and creation/use activity evidence while preserving carrier boundaries. Evidence: `tests/utils/docs.test.ts`, `tests/api/docs.test.ts`.\n- [x] ✅ **Linked Art event identity proof (2026-07-06)**: `/api/records/{id}` and `/api/events/{id}` now have regression coverage for the Events pattern: `Period`, `Event`, and `Activity` records preserve names, timespans, places, actor responsibility, `caused_by`, strict `part_of` partitioning, contextual `during`, and relative `before`/`after` ordering, while object production/destruction references keep their temporal links instead of flattening them into dates. Evidence: `tests/api/records/by-id.test.ts`, `tests/api/entity-roles.test.ts`, `tests/api/activity.test.ts`.\n- [x] ✅ **MetaHistoryBook Update/Delete alignment (2026-07-05)**: after the accepted `204` callback proof, MetaHistoryBook first rechecked `type=Update` and `type=Delete` as explicit zeroes, then approved a two-ping plan. MetaMuseum deployed the real reviewed Met `437133` `Update` row, and MetaHistoryBook re-read `/api/activity?type=Update&limit=100` as `metahistorybook-harvester-prod` at `2026-07-05T19:50:30Z`: `totalItems: 1`, `1` item, real non-synthetic, conformant `object.id`/`object.sourceId`/`equivalent[]`/UTC `endTime`, and cross-reconciliation through `Q432253`. `type=Delete` remains explicit zero by agreement until a genuine upstream `404`/`410` tombstone exists. Evidence: [linked-art/metahistorybook-prod-harvest-evidence.md](linked-art/metahistorybook-prod-harvest-evidence.md).\n- [x] ✅ **ActivityStreams partner quickstart (2026-07-04)**: [linked-art/activity-stream-partner-quickstart.md](linked-art/activity-stream-partner-quickstart.md) now gives external partners copy/paste feed-read, cursor sync, object-feed, subscription, verification, and response-template steps while explicitly stating the quickstart is not adoption evidence. `pnpm activity:partner-pack` links the quickstart and still emits `consumerIds: []`, placeholder rows, and `needs-consumer-ids` until real partner-owned IDs exist. Evidence: `tests/docs/activity-stream-partner-quickstart.test.ts`, `tests/scripts/activity-partner-onboarding-pack-script.test.ts`.\n- [x] ✅ **MetaHistoryBook reciprocal harvest probe and rehearsal path (2026-07-05)**: MetaHistoryBook now exposes a live IIIF Change Discovery stream, and Meta Museum has a bounded read-only probe at `pnpm activity:metahistorybook:harvest` that checks collection/page shape, fixed page size, oldest-first UTC `Update` activities, last-page walk-back start, dereferenceable Linked Art `object.id`, Wikidata `equivalent` reconciliation hooks, and the CC0 metadata `Link rel=license` header on both the collection and a sample record before any full-corpus import is considered. `pnpm activity:metahistorybook:import-rehearsal` adds the next rehearsal-only gate: capped page walk, capped record dereference sample, CC0 metadata-only rights mapping, QID mapping, and media-rights separation without adding a provider claim; after the partner approved moving the schedule forward, the latest larger rehearsal walked `562/562` pages, saw `56,196` activities, sampled `250/250` records, and mapped `250/250` metadata rights plus `250/250` QIDs. `pnpm activity:provider-backfill:evidence` now proves Meta Museum's own Met `record-backfill` publication rows separately from historic semantic events; the local gate covers `53` backfill rows, `53/53` real non-epoch timestamps, `53/53` equivalents, canonical MetaMuseum activity object IDs, and source/Wikidata equivalents synthesized for dereferenced records. MetaHistoryBook's July 5 production run as `metahistorybook-harvester-prod` passed multi-page ordering, real timestamps, `equivalent[]` reconciliation, and dedupe; it also proved the first concrete Met-to-MetaHistoryBook join on `Q432253` (`Garden at Sainte-Adresse`). Daily (`daily-metahistorybook-prod`) is filed as a second distinct external product consumer after walking the same 53 Met activities into an artwork-of-the-day candidate pool with 15 paintings and cursor `2026-05-31T10:40:54.290Z`; its public callback at `https://daily.metahistorybook.com/api/consumer/met/callback` now verifies for `Create`/`Update`/`Delete` and is filed as the first durable callback row. The rights mapping boundary is explicit: CC0 covers MetaHistoryBook's derived JSON metadata, while referenced image/media licenses remain separate. Checklist: [linked-art/metahistorybook-reciprocal-harvest-checklist.md](linked-art/metahistorybook-reciprocal-harvest-checklist.md). Evidence: `docs/linked-art/metahistorybook-prod-harvest-evidence.md`, `artifacts/activity-syndication/daily-metahistorybook-prod-callback-2026-07-05.json`, `src/services/metahistorybook-harvest.ts`, `src/services/metahistorybook-import-rehearsal.ts`, `src/services/activity-provider-backfill-evidence.ts`, `tests/services/metahistorybook-harvest.test.ts`, `tests/services/metahistorybook-import-rehearsal.test.ts`, `tests/services/activity-provider-backfill-evidence.test.ts`, `tests/scripts/metahistorybook-harvest-probe-script.test.ts`.\n- [x] ✅ **Activity discovery duplicate collapse (2026-07-05)**: default `/api/activity/collection` and `/api/activity/page/{page}` responses now collapse duplicate rows for the same `object.id`, preferring deletion, audit, and `record-backfill` publication signals over historic `record-semantic` rows so walk-back harvesters see one latest-change item per object by default. Explicit `source=record-semantic` and `source=record-backfill` filters still expose source-specific rows for diagnostics and evidence checks. Evidence: `src/services/activity-feed.ts`, `app/api/activity/collection/route.ts`, `app/api/activity/page/[page]/route.ts`, `tests/api/activity-as2.test.ts`.\n- [x] ✅ **Production activity backfill seed (2026-07-05)**: external checks showed `www.metamuseum.org` had the latest activity code but only the single clean-deploy `record-003` seed, so `provider=met` and `source=record-backfill` returned `0` rows despite the local gate being green. `data/sample-records.json` now carries the 53 Met records needed for the public `record-backfill` corpus, and `tests/fixtures/production-seed-records.test.ts` guards the seed for 53 Met rows, real non-epoch `importedAt` values, and reconciliation/source hooks.\n- [x] ✅ **External activity stream candidate registry (2026-07-05)**: `/api/providers/capabilities` now exposes read-only standards-stream candidates separately from provider ingest claims: Getty IIIF Change Discovery is `probe-ready`, Rijksmuseum LDES is `route-available` via `/api/rijks/ldes`, and Europeana/CoGent LDES remain watchlist references. Candidate notes: [linked-art/external-activity-streams.md](linked-art/external-activity-streams.md). Evidence: `src/services/external-activity-sources.ts`, `tests/services/external-activity-sources.test.ts`, `tests/api/providers/capabilities.test.ts`.\n- [x] ✅ **ActivityStreams adoption controls**: [`src/services/activitystreams-adoption-controls.ts`](../src/services/activitystreams-adoption-controls.ts) and [`tests/services/activitystreams-adoption-controls.test.ts`](../tests/services/activitystreams-adoption-controls.test.ts) now summarize and regression-check feed-read telemetry, partner-pack acceptance rows, durable HTTPS callback verification, strict review-goals selected checks, and placeholder/derived/local evidence rejection for the `0/3` real-consumer lane.\n- [x] ✅ **Commercial readiness controls**: [`src/services/commercial-readiness-controls.ts`](../src/services/commercial-readiness-controls.ts) and [`tests/services/commercial-readiness-controls.test.ts`](../tests/services/commercial-readiness-controls.test.ts) now summarize and regression-check the pre-revenue `/pilot` claim boundary, buyer-pack acceptance ledger, invoice-backed entitlement guard, monthly KPI/retention/gross-margin packet, and manual concierge versus repeatable subscription packaging gate.\n- [x] ✅ **Security reliability controls**: [`src/services/security-reliability-controls.ts`](../src/services/security-reliability-controls.ts) and [`tests/services/security-reliability-controls.test.ts`](../tests/services/security-reliability-controls.test.ts) now keep rotated-secret hygiene, production test-token rejection, membership-validated org-scope route coverage, and cron `CRON_SECRET` fail-closed behavior tied to one executable regression report.\n- [x] ✅ **Testing gap controls**: [`src/services/testing-gap-controls.ts`](../src/services/testing-gap-controls.ts) and [`tests/services/testing-gap-controls.test.ts`](../tests/services/testing-gap-controls.test.ts) now preserve complete onboarding coverage, scheduled disabled-feature drills, the `pnpm typecheck` release-command contract, storage-scope matrix breadth, and local-vs-strict evidence separation in one executable regression report, including acceptance-ledger links for every strict external contract and the no-global-bypass readiness downgrade.\n- [x] ✅ **Complete onboarding e2e regression**: [`tests/e2e/onboarding-flow.test.ts`](../tests/e2e/onboarding-flow.test.ts) now walks the high-value launch path as one executable journey: public users hit the sign-in gate, a signed-in editor selects an active org, imports a provider record into org-scoped storage, creates an approval-required AgentTask review, approves a wiki draft, proves dry-run publication stays non-live, and exercises the publish-queue daily-cap boundary.\n- [x] ✅ **Secret rotation preflight guard**: production `pnpm launch:preflight:production` now requires non-secret rotation evidence and a git tracking/history probe for sensitive `.env*` files through `security.secretRotation` and `security.secretHistory`, and review-goals selects both rows as launch-readiness evidence.\n- [x] ✅ **Secret evidence stale-artifact handoff**: when an older `artifacts/launch/deployment-preflight-latest.json` is missing `security.secretRotation` or `security.secretHistory`, `pnpm review:goals` now reports the artifact as stale or missing current selected-check coverage, points to `pnpm launch:preflight:production`, and keeps the exact rotation/history acceptance criteria visible.\n- [x] ✅ **Production preflight latest-artifact protection**: `pnpm launch:preflight:production` now treats localhost/private production-target runs as diagnostics by keeping the timestamped run artifact while refusing to replace `deployment-preflight-latest.json`, so local `.env` defaults cannot accidentally become the review-goals launch evidence packet.\n- [x] ✅ **Production launch-review public Era C handoff**: production `pnpm launch:review:production` now points red or stale Era C evidence at `pnpm era-c:exit-gate:public` so operators refresh probe-backed public evidence instead of local telemetry, while staging review keeps `pnpm era-c:exit-gate:evidence` for rehearsal.\n- [x] ✅ **Explicit-env production preflight mode**: `METAMUSEUM_SKIP_ENV_FILES=1` now lets production evidence runs ignore local `.env*` files so staging-only values such as `METAMUSEUM_TEST_ROLE_OVERRIDE_TOKEN` cannot contaminate the public launch artifact. The latest explicit-env dry run proved the new `security.secretRotation` and `security.secretHistory` checks pass when non-secret rotation evidence and git history probes are supplied; strict `/api/validate` is now production-default closed unless `METAMUSEUM_STRICT_VALIDATION_PUBLIC=1` is set.\n- [x] ✅ **Render strict-validation cold-start guard**: `VALIDATION_TIMEOUT_MS` now bounds strict `/api/validate`, while production preflight keeps the long Render `/health` cold-start probe separate from user-facing readiness by treating Render validation as operator-only unless public strict validation is explicitly enabled. If `METAMUSEUM_STRICT_VALIDATION_PUBLIC=1` is set, preflight still fails without paid/no-sleep capacity evidence or within-budget health duration.\n- [x] ✅ **TypeScript command drift retired**: `pnpm typecheck` remains the CI-aligned production signal, while `pnpm typecheck:diagnostic` now converges with direct `tsc --noEmit`; `pnpm typecheck:diagnostic:report` writes JSON/Markdown parity artifacts with `status: converged`, `0` errors, `0` buckets, and `0` unclassified diagnostics. The command contract is in [`docs/development/typescript-command-contract.md`](development/typescript-command-contract.md).\n- [x] ✅ **Era A + Era B**: legacy lift, parity, provider hardening, authority caching, B6.1 reconciliation, B7 gateway readiness/facade, B8 protocol conformance, B9 modeling guardrails, B10 ARK behavior, and pre-Era-C operational sign-off are complete.\n- [x] ✅ **Era C implementation surface**: C1-C5 core features are implemented, including multi-modal storage scaffolding, HAL/search/activity endpoints, C2 ETL/reconciliation/mapper, C3 IIIF + visualization surfaces, C4 AI query/chat/evals/mapping assist, specialized review agents, and C5 syndication/wiki/security/privacy hardening.\n- [x] ✅ **AI agent review layer**: five single-word field-aligned agents are live behind human approval: Clio (research signals), Mercator (Linked Art mapping review), Janus (reconciliation review), Themis (rights/provenance review), and Calliope (citation-backed curatorial drafts). Localhost smoke completed all five, avatar assets are verified, each returned AgentTask persists to editor-gated review history at `/api/agents/tasks`, and Mercator/Janus now have a disabled-by-default AG2 bridge boundary plus local review-only FastAPI worker with trace propagation, contract validation, timeout/refusal fallback, local fallback, safe enablement docs, and live-worker eval artifacts. AgentTask outputs now include reviewer-facing evidence diagnostics: Clio sparse-scope missing signals and next evidence, Mercator unmapped sensitive-column explanations, Janus reconciliation candidate-readiness plus zero-candidate reasons, Themis structured-rights/provenance evidence checks, and Calliope source-note citation-review snippets. `src/services/ai-agent-safety-controls.ts` and `tests/services/ai-agent-safety-controls.test.ts` now keep the safety posture executable across agent/model-spend RBAC, anonymous model downgrade, cite-or-refuse gates, approval-required AgentTask defaults, and opt-in AG2 bridge drills.\n- [x] ✅ **Disabled-system staging drill**: `pnpm staging:disabled-drill:check` now writes `artifacts/staging-disabled-systems/latest.json` and rehearses off-by-default AG2 fallback, enabled AG2 contract delegation with a mocked worker, Solr/GraphDB projection skip/no-network behavior, mocked enabled Solr/GraphDB request dispatch, projection readiness scale-pressure blockers, disabled cron no-ops, publication disabled-channel handling, and enabled publication webhook dispatch before those systems are enabled for real staging or production use; `.github/workflows/staging-disabled-systems-drill.yml` runs the same staging check weekly and uploads the latest/timestamped artifacts, with service, script, workflow, and testing-gap regressions asserting the expanded 9-check schedule contract.\n- [x] ✅ **SEO/content publishing policy**: generated article, book, object-label, and collection-brief outputs now include source-derived SEO metadata (`seoTitle`, meta description, primary/secondary keywords, H1, subheadings, slug, rationale) on both accepted and refused content paths; WikiDrafts validate the same SEO envelope while preserving canonical source titles and citation/originality gates.\n- [x] ✅ **Security/privacy posture**: PII/sensitivity scan, review holds, audited human disposition, rights/reuse UI warnings, and public projection controls are active before Solr/GraphDB syndication.\n- [x] ✅ **Governance + docs contract**: markdown under `docs/` remains the canonical source of truth, surfaced by `/docs`, `/api/docs/manifest`, and `/api/docs/content`; Linked Art reference mapping, AIDD/TDD, and closeout evidence remain mandatory. `pnpm product:constraints:check` now makes Linked Art conformance and rights-first publication non-negotiable by checking the generated conformance command/docs/tests, `Right` entity modeling, WikiDraft rights-warning publication guards, cite-or-refuse coverage, and human approval policy. `pnpm review:goals` now gives the 10/10 review-goal audit a blocker-preserving JSON and Markdown artifact, with each JSON artifact carrying a `$schema` pointer to `docs/schemas/review-goals.schema.json`, per-goal `evidenceArtifacts` paths, observed `evidenceArtifactStatuses`, selected `evidenceArtifactCheckStatuses`, structured per-goal `externalEvidenceBlockers`, and a flattened report-level blocker list for launch evidence/preflight/review checks, Render service probes, managed-pilot entitlement/outreach/activation/support/KPI evidence, long-term runway checks, Era C exit-gate `sota204P95`/`publicReadUptime`/`activityFeedAdoption`/`sota26Kpis` checks, ActivityStreams consumer/subscription checks, and paid-pilot proof. Those selected checks are readiness gates: local gates can be complete while real SLO, uptime, ActivityStreams consumer, KPI, and paid-pilot evidence remain explicitly external, no high-level flag can produce a 10/10 report while a selected artifact check is failing or missing, and bounded or fail-fast launch evidence still leaves a full packet behind with skipped remainder steps plus structured remediation, next evidence, command, and artifact fields preserved in the top-level audit. `SUPPORT.md` now gives contributors and operators an explicit issue, PR, security advisory, pilot evidence, launch blocker, and conformance escalation path without inventing an undocumented chat channel. The normal `pnpm session:closeout` path now refuses to append unless `README.md` and this roadmap were updated since the previous closeout.\n- [x] ✅ **Deployment (LIVE)**: the Next.js app is deployed to **production on Vercel against Neon Postgres** (`storageMode=postgres`), verified serving real records and public pages (2026-06-23). `vercel.json` pins `next build` so the close-out guard cannot break builds; the guard also self-skips when `VERCEL` is set. The `render.yaml` FastAPI validation and reconciliation services plus Redis cache are now deployed on Render, and both `/health` endpoints are included in launch readiness probes when their URLs are passed to `pnpm launch:evidence:production`. Secured Vercel Cron drains for outbox projection and publish queue processing are now configured at `/api/cron/outbox` and `/api/cron/publish`; both require `CRON_SECRET` and remain opt-in behind worker env flags until Solr/GraphDB projection or wiki/publication publishing is intentionally enabled. `/workers` and `/api/workers/status` now make scheduled-drain state explicit with worker lag, backlog, next cron wakeup, effective next drain, disabled projection/publish modes, and blocked/dead-letter signals. Direct Solr/GraphDB projection now also skips when target flags are unset, matching the read-only deploy contract. Deployment preflight now fails production when `BASE_URL` and `METAMUSEUM_PUBLIC_READ_BASE_URL` are missing, divergent, localhost, non-HTTPS, or otherwise not the same shareable public HTTPS URL, and runtime social metadata resolves against the public-read base before Vercel preview fallbacks. Documentation drift guards now keep Vercel/Neon launch examples aligned on the canonical public URL pairing and Neon `sslmode=verify-full`, including `.env.example`. Preflight now also probes live Auth.js `/api/auth/signin` and `/api/auth/session` routes so auth readiness is route evidence, not only secret presence, and fetches `IIIF_TILE_URL` so k6 tile evidence cannot point at a broken or protected target. Probe-based uptime history now keeps per-route URL, status, duration, and error/protection detail for public-read checks, making failed uptime samples and deployment-protection regressions diagnosable from the evidence artifact while the 30-sample window fills. `pnpm longterm:evidence` now records the daily 09:15 UTC collection cadence, next scheduled run, missing distinct SLO/uptime days, missing external-consumer count, and earliest possible ready date in the long-term evidence `collectionPlan`, so the 30-day blocker has an operator-visible runway instead of a vague wait state. Optional Render validation/reconciliation dependencies are now explicit in deployment preflight: unset URLs record the local fallback/in-process mode, while configured service URLs get `/health` status and duration evidence so cold starts and timeouts are visible in launch readiness artifacts. `pnpm activity:syndication:evidence` now ties real declared external ActivityStreams consumers to active external HTTPS subscriptions for the same IDs, keeps accepted/rejected callback rows in the artifact, and counts only public non-placeholder callback hosts that match their HTTPS callback URL, were updated inside the evidence window, cover Create/Update/Delete, and carry recent 2xx callback verification proof, keeping durable syndication blocked until partner callback workflows are fresh, complete, and verified. `pnpm smoke:crawler-preview` now records Facebook, Slack, Googlebot, LinkedIn, and X/Twitter-facing Open Graph/Twitter/canonical checks plus preview image fetchability in launch artifacts. `pnpm launch:evidence` and `pnpm launch:evidence:production` now run hardening security/DR, preflight, public trust, crawler preview, a11y, explore, k6, Era C exit-gate, and launch review as one blocker-preserving evidence packet, and failed/skipped steps name the remediation command plus artifact path operators should turn green next. The route-storage guard now walks production API import paths and blocks unmanaged local JSON writes; activity subscriptions, AI query usage logs, issue cache, and publish queue persistence are Postgres-managed documents instead of Vercel filesystem writes. See [deployment.md](deployment.md).\n  Review-goal deployment evidence now distinguishes deployed Render service probes from documented local fallback mode: `pnpm review:goals` only counts the validation/reconciliation service goal when both selected checks show passing public HTTPS Render `/health` probes, rejects HTTP, non-health, placeholder, local, or private-network probe text, and launch readiness also selects those same deployed service checks. Launch readiness additionally selects worker scheduler readiness, Auth.js secret, GitHub OAuth credential, live signin/session route, production public-base URL, social-preview base URL, database authentication, deployment activation freshness, and public-read uptime source checks from deployment preflight, plus crawler-preview checks from both launch evidence and launch review, so missing cron/secret wiring, localhost, non-HTTPS, protected, mismatched share URLs, missing auth credentials, stale database credentials, stale active Vercel deployments, missing uptime-source setup, or missing Render service probes stay explicit deployment blockers before Open Graph/Twitter/canonical, preview-image, public-read, a11y, and probe-based uptime evidence can be trusted; the `launchEvidenceReady` coarse flag now requires those selected launch-evidence, launch-review, and deployment-preflight rows before it can pass. The long-term goal now also selects the Era C exit-gate `sota204P95`, `publicReadUptime`, `activityFeedAdoption`, and `sota26Kpis` rows, so measured p95 misses, insufficient uptime depth, missing external consumers, and KPI export gaps are real-world blockers with `pnpm era-c:exit-gate:public` remediation rather than a single opaque exit-gate failure; its coarse readiness flag requires both the selected runway rows and Era C rows before counting 30-day evidence ready. Manual public evidence refreshes should use `pnpm monitoring:telemetry:public`, `pnpm era-c:exit-gate:public`, or `pnpm longterm:evidence:public`, which force probe-backed uptime against `https://www.metamuseum.org` and avoid inheriting localhost from `.env.local`. The ActivityStreams coarse readiness flag now requires both selected rows, `activity.declaredConsumers` and `activity.durableSubscriptions`, before counting syndication ready, so a top-level ready artifact cannot hide missing or unverified durable subscriptions. The version-45 audit also scopes production launch-packet a11y failures to the deployment-environment lane instead of treating them as local-refresh debt, and includes `analytics-consent-posture` as a local governance goal backed by `pnpm privacy:consent:check` and `artifacts/privacy/analytics-consent-latest.json`. Coarse external blocker rows and selected artifact-check rows now include their own next-evidence text, remediation commands, and artifact targets for launch, Render probes, 30-day SLO/uptime, Era C exit-gate, ActivityStreams syndication, paid-pilot evidence, and consent-posture checks, with a command-and-scope `nextActions` list that unions every artifact path into machine-readable `artifactTargets`, preserves each blocker as a goal-scoped action `blockerIds` reference whose length matches `blockerCount`, preserves every distinct evidence requirement as `nextEvidenceRequirements`, keeps local/deploy/real-world queueing as `executionScope`, exposes top-level lane counts as `nextActionSummary.actionCount`, includes blocker-lane `externalEvidenceBlockerSummary.nextActionIds`, `actionCount`, `nextEvidenceRequirements`, and `requirementCount`, includes per-goal `blockedByExternalEvidenceGoals.nextEvidenceRequirements`, `requirementCount`, `actionCount`, `commandCount`, `artifactCount`, and `scopeCount`, reports the local-only CI result as top-level `localGateStatus`, reports the final strict gate as top-level `strictGateStatus`, lists the strict-gate blocker lanes in `strictGateFailureReasons`, adds structured strict-gate rows in `strictGateFailureSummary`, adds consolidated strict-gate commands/artifacts/goals in `strictGateHandoff`, includes exact blocker IDs in `strictGateHandoff.blockerIds` and `strictGateHandoff.scopeBreakdown[].blockerIds`, includes exact action IDs in `strictGateHandoff.nextActionIds` and `strictGateHandoff.scopeBreakdown[].nextActionIds`, includes explicit strict next-action totals in `strictGateHandoff.nextActionCount` and `strictGateHandoff.scopeBreakdown[].nextActionCount`, includes explicit affected-goal totals in `strictGateHandoff.goalCount` and `strictGateHandoff.scopeBreakdown[].goalCount`, includes distinct remediation-command totals in `strictGateHandoff.commandCount` and `strictGateHandoff.scopeBreakdown[].commandCount`, includes distinct evidence-artifact target totals in `strictGateHandoff.artifactCount` and `strictGateHandoff.scopeBreakdown[].artifactCount`, includes distinct next-evidence requirement totals in `strictGateHandoff.requirementCount` and `strictGateHandoff.scopeBreakdown[].requirementCount`, includes consolidated strict-gate next-evidence sentences in `strictGateHandoff.nextEvidenceRequirements`, splits those strict handoffs by scope in `strictGateHandoff.scopeBreakdown`, and exposes both `score.blockedByExternalEvidence` and `blockedByExternalEvidenceGoals` so local-gate-complete goals do not hide the true external-blocked total or the named goal handoffs. Each blocked-goal row now carries exact blocker IDs, action IDs, action-level blocker/artifact/requirement counts, action counts, scopes, scope counts, remediation commands, command counts, artifact targets, artifact counts, distinct top-level evidence requirements and counts, an `actionBreakdown` mapping each command to the blockers it remediates with goal-local evidence requirements, and a `scopeBreakdown` that splits that goal's action, next-action ID, blocker, command, artifact, and requirement arrays and totals across local-refresh, deployment-environment, and real-world-evidence lanes; the schema now requires those blocked-goal handoff arrays to be populated and duplicate-free before the artifact contract is considered valid. The latest local audit reports `complete=7/12`, with launch readiness, Render service probes, managed pilot, 30-day SLO/uptime, and ActivityStreams syndication named in `blockedByExternalEvidenceGoals`. The local-refresh lane has `0` blockers, deployment-environment has `4` blockers driven by launch-evidence, launch-review, Era C proof, and Render service probes, and the real-world lane still has `19` blockers for long-window, ActivityStreams `Delete` type coverage, KPI, and pilot proof. `pnpm review:goals:local` now lets CI fail only on missing local commands/docs/tests while `pnpm review:goals:check` stays reserved for the final real-evidence 10/10 gate; documentation drift tests scan public docs for stale demo-script-only, launch-preflight-green, strict-handoff count drift, and broad-public-SaaS readiness claims that bypass that strict gate, and the Era C evidence workflow enforces the local gate before uploading the review-goals packet.\n- [x] ✅ **Review-goals version 44 consent posture gate**: `pnpm privacy:consent:check` now writes `artifacts/privacy/analytics-consent-latest.json`, and review goals include the GA4 consent posture as a governance goal with local script, docs, tests, and artifact checks.\n- [x] ✅ **Review-goals version 42 scoped blocked-goal actions**: `blockedByExternalEvidenceGoals[].scopeBreakdown[].nextActionIds` now lets each blocked-goal scope join directly to grouped remediation actions.\n- [x] ✅ **Review-goals version 41 blocked-goal scope counts**: `blockedByExternalEvidenceGoals[].scopeCount` now exposes how many execution lanes remain for each named blocked goal.\n- [x] ✅ **Review-goals version 40 blocked-goal totals**: `blockedByExternalEvidenceGoals[].actionCount`, `commandCount`, and `artifactCount` now expose dashboard-ready blocked-goal handoff totals directly.\n- [x] ✅ **Review-goals version 39 blocked-goal requirements**: `blockedByExternalEvidenceGoals[].nextEvidenceRequirements` and `requirementCount` now make each named blocked goal self-contained with exact acceptance criteria.\n- [x] ✅ **Review-goals version 38 external blocker actions**: `externalEvidenceBlockerSummary[].nextActionIds` and `actionCount` now point each blocker lane directly at grouped remediation actions.\n- [x] ✅ **Review-goals version 37 external blocker requirements**: `externalEvidenceBlockerSummary[].nextEvidenceRequirements` and `requirementCount` now expose acceptance criteria directly per blocker lane.\n- [x] ✅ **Review-goals version 36 action-summary counts**: `nextActionSummary[].actionCount` now exposes action totals per execution-scope lane while legacy `count` remains for compatibility.\n- [x] ✅ **Review-goals version 35 strict action counts**: `strictGateHandoff.nextActionCount` and scoped `strictGateHandoff.scopeBreakdown[].nextActionCount` now expose executable action totals directly, so dashboards do not have to count action ID arrays.\n- [x] ✅ **Review-goals version 34 blocked-goal scoped payloads**: `blockedByExternalEvidenceGoals[].scopeBreakdown[]` now includes scoped remediation commands, artifact targets, and next-evidence requirements, so each named blocked goal can be handed to an operator without joining through action rows.\n- [x] ✅ **Review-goals version 33 blocked-goal scope counts**: `blockedByExternalEvidenceGoals[].scopeBreakdown[]` now exposes action, command, artifact, and requirement counts per scope, so each named blocked goal carries dashboard-ready handoff totals without parsing nested arrays.\n- [x] ✅ **Review-goals version 32 strict requirement counts**: `strictGateHandoff.requirementCount` and scoped `strictGateHandoff.scopeBreakdown[].requirementCount` now expose distinct next-evidence acceptance-criteria totals directly, so dashboards can show how many criteria remain without parsing long requirement text.\n- [x] ✅ **Review-goals version 31 strict artifact counts**: `strictGateHandoff.artifactCount` and scoped `strictGateHandoff.scopeBreakdown[].artifactCount` now expose distinct evidence-artifact target totals directly, so dashboards do not have to count artifact arrays before showing the remaining evidence packet footprint.\n- [x] ✅ **Review-goals version 30 strict command counts**: `strictGateHandoff.commandCount` and scoped `strictGateHandoff.scopeBreakdown[].commandCount` now expose distinct remediation-command totals directly, so dashboards do not have to count command arrays or confuse distinct commands with scoped action rows.\n- [x] ✅ **Review-goals version 29 strict goal counts**: `strictGateHandoff.goalCount` and scoped `strictGateHandoff.scopeBreakdown[].goalCount` now expose affected-goal totals directly, so dashboards do not need to count goal arrays.\n- [x] ✅ **Review-goals version 28 strict action IDs**: `strictGateHandoff.nextActionIds[]` and scoped `strictGateHandoff.scopeBreakdown[].nextActionIds[]` now point from the strict-gate handoff directly to the executable `nextActions[]` rows, so operators do not have to reconstruct command/scope keys.\n- [x] ✅ **Review-goals version 27 strict blocker IDs**: `strictGateHandoff.blockerIds[]` and scoped `strictGateHandoff.scopeBreakdown[].blockerIds[]` now name the exact failing checks behind the strict gate, so operators can trace a blocker directly to the artifact/check row without joining through goals.\n- [x] ✅ **Review-goals version 26 strict scope breakdown**: `strictGateHandoff.scopeBreakdown[]` now splits strict-gate commands, artifacts, affected goals, blocker counts, and next-evidence requirements by execution scope, so deployment setup and real-world proof cannot be merged in the final operator handoff.\n- [x] ✅ **Review-goals version 25 strict evidence requirements**: `strictGateHandoff.nextEvidenceRequirements[]` now unions the exact next-evidence sentences from scoped action rows, so the strict-gate handoff carries the commands, artifact paths, and evidence acceptance criteria together.\n- [x] ✅ **Review-goals version 24 strict handoff**: `strictGateHandoff` now consolidates strict-gate summary IDs, execution scopes, blocker count, affected goals, remediation commands, and artifact targets into one schema-locked operator payload, so launch dashboards can show remaining deployment and real-world proof without rejoining summary rows.\n- [x] ✅ **Review-goals version 23 strict summary invariants**: runtime invariants now validate every structured `strictGateFailureSummary[]` field against the derived blocker summaries, so strict-gate dashboard rows cannot silently drift in counts, goals, commands, artifacts, scope, kind, or reason text.\n- [x] ✅ **Review-goals version 22 structured strict failure summary**: `strictGateFailureSummary[]` now gives dashboards closed rows with kind, scope, blocker counts, affected goals, commands, artifacts, and the matching reason, so deployment-environment and real-world evidence lanes can be consumed without parsing prose.\n- [x] ✅ **Review-goals version 21 strict failure reasons**: `strictGateFailureReasons[]` now lists the non-empty blocker lanes and remediation commands when the strict 10/10 gate fails, so local-green reports explain the remaining deployment and real-world evidence work directly in JSON and Markdown.\n- [x] ✅ **Review-goals version 20 strict gate status**: `strictGateStatus` now records the final `pnpm review:goals:check` pass/fail result separately from `localGateStatus`, so local-green reports with remaining production, partner, customer, or 30-day evidence blockers cannot be misread as 10/10-ready.\n- [x] ✅ **Review-goals version 16 handoff shape**: `nextActionSummary[]` now carries distinct commands, artifact targets, goal IDs, titles, categories, and counts per execution scope, so the deployment-environment and real-world-evidence lanes show which 10/10 goals they affect and which outputs they refresh without requiring dashboards or operators to join through `nextActions`.\n- [x] ✅ **Review-goals version 17 blocker scopes**: goal-level and report-level external-evidence blocker rows now carry `executionScope` directly, so each blocker is visibly `deployment-environment` or `real-world-evidence` at the row level instead of requiring a join through `nextActions`.\n- [x] ✅ **Review-goals version 19 scoped actions**: `nextActions[]` now groups by remediation command plus execution scope, so shared commands such as `pnpm era-c:exit-gate:evidence` can produce separate deployment-environment and real-world-evidence action rows instead of mixing blocker lanes.\n- [x] ✅ **Review-goals version 18 blocker summaries**: `externalEvidenceBlockerSummary[]` now groups raw blocker rows by execution scope with blocker IDs, goals, remediation commands, and artifact targets, so deployment and real-world blocker debt remains visible even before operators inspect grouped actions.\n- [x] ✅ **Review-goals invariant guard**: the CLI now refuses to write malformed review-goals artifacts when score totals, blocked-goal counts, blocker counts, unknown action references, scope summaries, commands, artifact targets, or goal lists drift from the generated report body.\n- [x] ✅ **Review-goals version alignment**: `REVIEW_GOALS_REPORT_VERSION`, emitted report `version`, and JSON schema `version.const` are test-locked together so artifact contract bumps cannot split the service and schema.\n- [x] ✅ **Review-goals schema parity guard**: generated JSON artifacts are runtime-validated against the schema-required keys and closed-object sections for report, score, goal, evidence, blocked-goal, action, and action-summary rows before the CLI prints or writes them, so schema/report drift fails before operators receive a malformed 10/10 evidence handoff.\n- [x] ✅ **Portfolio README + docs (2026-06-24)**: README trimmed from ~1,300 lines to a lean hero + highlights + run-it + honest \"what's real vs. in progress\" (detailed status stays here in the roadmap). New deep-dives added: [responsible-ai.md](responsible-ai.md) (key handling, denial-of-wallet auth-gate, citation/refusal gates, eval harness, cost control) and [linked-art/conformance-matrix.md](linked-art/conformance-matrix.md) (protocol MUSTs verified live + per-provider matrix + honest gaps). A single-file architecture/reviewer HTML handoff is maintained at [metamuseum-project-overview.html](metamuseum-project-overview.html) for browser-openable reviewer context.\n- [x] ✅ **README density refresh (2026-06-28)**: the README no longer carries the long review-goals artifact-version history or operator-level schema prose; it now gives fast reviewers a short strict-readiness summary and links to [docs/ops/review-goals.md](ops/review-goals.md) for the detailed artifact contract.\n- [x] ✅ **Linked Art rights as `Right` entities — all providers (2026-06-24)**: started the [roadmap to 10/10](roadmap-to-10.md) with milestone **B1**. `src/utils/linked-art-rights.ts` synthesizes a conformant `subject_to` `Right` (classified by CC0 / rightsstatements.org URIs) for every object record that lacks one, wired into both `normalizeIncomingRecord` and the read-path `migrateToCurrentSchema`; Getty's are preserved. Closes the \"rights as labels outside Getty\" gap in the conformance matrix.\n- [x] ✅ **Reliable, badged CI — roadmap-to-10 A1 (2026-06-24)**: the session close-out guard no longer fails CI — `scripts/session-closeout.ts` skips the `--check` guard when `CI` is set (it stays enforced locally), so a stale local close-out log can't turn a green build red (the PR #16 failure mode). README header now carries CI / License / Linked Art / tests badges, and the tests badge intentionally uses a guarded `1,100+` label rather than an exact stale-prone count.\n- [x] ✅ **Supply-chain hygiene — roadmap-to-10 A2 (2026-06-24)**: resolved all 3 moderate `pnpm audit --prod` advisories via `pnpm.overrides` (postcss XSS → `>=8.5.10`; OpenTelemetry memory-DoS → core/resources/sdk-trace-base `^2.8.0`, which also fixes `@vercel/otel`'s mis-resolved 1.30.1 peers). Added `.github/dependabot.yml` (npm + github-actions + 4 pip services) and a `pnpm audit --prod --audit-level high` CI gate. Audit clean; tests 1,114; build green.\n- [x] ✅ **Per-provider conformance matrix generated — roadmap-to-10 B3 (2026-06-24)**: the 14×2 per-provider pass/fail fixtures (asserted in CI by `validation-architecture-depth.test.ts`) now drive a **generated** conformance matrix via `scripts/generate-conformance-matrix.ts` (`pnpm conformance:matrix`); `conformance-matrix-generated.test.ts` gates drift. The published `conformance-matrix.md` table is no longer hand-maintained. 14/14 providers pass both directions.\n- [x] ✅ **SHACL conformance gate in CI — roadmap-to-10 B2 (2026-06-24)**: `services/validation-service/shacl_gate.py` + `.github/workflows/shacl-conformance.yml` validate every provider's pass fixture against the Linked Art SHACL shapes with pyshacl (JSON-LD → CIDOC-CRM RDF). Path-filtered job; `pnpm shacl:gate` locally. All 14 pass fixtures conform; a CRM-expansion regression now blocks the build.\n- [x] ✅ **Measured + gated test coverage — roadmap-to-10 A3 (2026-06-24)**: `pnpm test:coverage` runs the suite under c8 with a `--check-coverage` gate (lines 85 / funcs 85 / branches 70); CI's test step now enforces it. Current 89.4% lines / 92.1% funcs (core `src/services` 91.9%). README coverage badge added; also fixed CRLF-fragility in the B3 drift test so coverage runs clean cross-platform.\n- [x] ✅ **Published quality scores — roadmap-to-10 A4 (2026-06-24)**: [`docs/quality.md`](quality.md) publishes CI-measured numbers — Lighthouse a11y **100/100** on key pages, axe **0 severe** WCAG 2A/2AA violations across 18 routes, and the k6 p95 performance budget **met** (cached 73.5 ms, cold 56.1 ms, facet 55.1 ms, 0% errors). README a11y badge added.\n- [x] ✅ **Faceted / relevance search — roadmap-to-10 B4 (2026-06-24)**: `src/services/search.ts` ranks `/api/search` results by hit quality (exact label > prefix > substring > name) and returns `type`/`provider` facet counts + `q`/`type`/`provider`/`limit`/`offset` params in the `ld+json` `OrderedCollectionPage`. Tested at the service + API level; conformance-matrix \"basic, not faceted\" gap closed (Solr 9 documented as the env-gated scale backend).\n- [x] ✅ **Fixed flaky annotations test / CI reliability (2026-06-24)**: annotation ids were `annotation-${Date.now()}`, so two creates in the same millisecond shared an id — letting annotations in different org scopes collide and intermittently breaking the cross-org isolation assertion in CI. Centralized id minting in `mintAnnotationId()` (timestamp + `randomUUID`); added a deterministic 1,000-mint uniqueness test. Completes the A1 \"reliable CI\" goal.\n- [x] ✅ **HEAD + HTTP/2 conformance — roadmap-to-10 B6 (2026-06-24)**: the canonical Linked Art entity/collection routes now export `HEAD` (via a `bodilessResponse(await GET(...))` helper in `src/utils/protocol.ts`) — same headers as GET, no body, mirrors 200/404; `OPTIONS` advertises `GET,HEAD,OPTIONS`. HTTP/2 verified live (`HTTP/2.0 200` via Vercel). `tests/api/head-methods.test.ts`; suite 1,128.\n- [x] ✅ **Roadmap trimmed — roadmap-to-10 A5 (2026-06-24)**: this roadmap went from ~1,510 lines to ~420 by archiving the slice-by-slice Era A/B/C history to [`progress/era-history.md`](progress/era-history.md) (see \"Era delivery history\" below). `getStructuredRoadmap` aggregates both files so `/api/roadmap` still exposes full phases/milestones.\n- [x] ✅ **Activity Streams change feed — roadmap-to-10 B5 (2026-06-24, lifted 2026-07-04)**: aligned `/api/activity` to Activity Streams 2.0 — AS2 `@context`, cursor-first `next`/`prev` page links (kept offset `nextPage`/`prevPage` aliases), a fuller `partOf` `OrderedCollection` with `first`/`last`/`totalItems`, `application/activity+json`, embedded Linked Art projections, semantic record-event extraction, filters, cursor sync, and object-scoped feeds. `tests/api/activity-as2.test.ts`, `tests/api/activity.test.ts`.\n- [x] ✅ **Product walkthrough + evaluator brief — roadmap-to-10 A6 (2026-06-29)**: the README now links a recorded no-narration public-site walkthrough at [`public/media/metamuseum-product-walkthrough.webm`](../public/media/metamuseum-product-walkthrough.webm), `/projects` presents it as a professional Linked Art SaaS product case study, and the shot-by-shot replacement script remains at [`demo-script.md`](demo-script.md). The current 10/10 gate is no longer a demo-media checklist; `pnpm review:goals:check` remains blocked on the launch-review Era C dependency, paid-pilot proof, 30-day SLO/uptime evidence, KPI exports, and durable ActivityStreams syndication.\n- [x] ✅ **Product case-study layout pass (2026-06-29)**: `/projects` now gives the CTA row, proof strip, case-study cards, architecture cards, and walkthrough media page-specific spacing and wrapping so buttons and cards do not touch or overlap across mobile, tablet, and desktop checks.\n- [x] ✅ **Standalone project overview HTML (2026-06-29)**: [`metamuseum-project-overview.html`](metamuseum-project-overview.html) now provides a single-file, browser-openable project overview with inline CSS/SVG only, covering essence, architecture, components, engineering discipline, state, risks, and evidence-based next improvements.\n- [x] ✅ **Dependency batch verified (2026-06-24)**: applied all 14 open Dependabot updates in one verified PR (#48) — fastapi 0.138, pyld 3.1, redis 8, pydantic 2.13, dagster 1.13.10, `actions/checkout` 6→7 — each installed in a clean venv and run against the relevant service's tests (validation `validate_record` + SHACL gate, reconciliation 9 tests, ag2-worker 6 tests, pipeline 3 tests). SHACL CI pins synced; queue cleared. Keeps A2 supply-chain hygiene current.\n- [ ] ⚠️ **Era C exit gate is not green yet**: latest evidence is still `failed`. The current strict handoff reports `20/30` retained deployed SLO samples across `7/30` observed days, with `13/30` passing samples across `6/30` passing days and `7` failed/incomplete retained rows. Public-read uptime has `126/129` passing retained checks across `10/30` observed days but only `0.9767` availability against the `0.999` target, ActivityStreams has `3/3` declared external consumers, restored `3/3` durable callback rows, and observed `Create, Update` type coverage while still missing real `Delete` read coverage, and production KPI exports still miss reconciliation thresholds. The project is strong for controlled beta/demo use, but not yet ready to claim full public-production completion.\n\n- [x] ✅ **Worker scale scheduler guard (2026-06-27)**: production preflight now fails if Solr/GraphDB projection targets are enabled without `CRON_SECRET` plus `METAMUSEUM_OUTBOX_CRON_ENABLED=1`, or if live MediaWiki/Wikibase endpoints or bot tokens are configured without `CRON_SECRET` plus `METAMUSEUM_PUBLISH_QUEUE_CRON_ENABLED=1`. A static Vercel config test also keeps `/api/cron/outbox` and `/api/cron/publish` scheduled before those scale flags can be treated as launch-ready.\n- [x] ✅ **Vercel Observability cron-error fix (2026-06-28)**: live probes showed `/api/cron/outbox` and `/api/cron/publish` returning `503 cron_secret_missing` while `/api/workers/status` showed both drains intentionally disabled. Disabled scheduled drains now return `200` no-op JSON without `CRON_SECRET`, while enabled drains still require bearer auth before any outbox or publish work can run; route-level tests cover the disabled no-op and enabled-secret cases.\n- [x] ✅ **Projection scale-readiness gate (2026-06-27)**: `pnpm projection:readiness` now writes `artifacts/launch/projection-readiness-latest.json` and classifies Solr/GraphDB projection as `portable`, `watch`, `enable`, or `enabled` based on current record count, active discovery/graph workflow counts, and search/graph p95 metrics. `pnpm projection:readiness:check` exits non-zero when the scale path is required but target/scheduler readiness is incomplete, so Solr/GraphDB projection is enabled only when volume and discovery workflows justify it.\n\n### Current Launch Readiness\n\n| Launch lane | Score | Current decision | Required next evidence |\n|---|---:|---|---|\n| Internal/dev demo | 9/10 | Safe to keep using and iterating locally. | Keep `pnpm test`, `pnpm lint`, `pnpm build`, and closeout guard green. |\n| Controlled public beta | 8.4/10 | App is now **live on Vercel + Neon** at `https://www.metamuseum.org` (2026-06-23), clearing the deployed-base-URL blocker. The July 3 production preflight passes `20/20`: OAuth, Postgres storage shape, `sslmode=verify-full`, live Neon authentication, active deployment freshness after secret rotation, auth/IIIF reachability, validation/reconciliation Render `/health` probes, public-read reachability, social-preview base URL parity, no production smoke override token, and secret-rotation/history evidence all pass. Strict `/api/validate` is operator-only by default in production unless `METAMUSEUM_STRICT_VALIDATION_PUBLIC=1` is set. The refreshed launch evidence packet passes `8/9`, launch review passes `7/8`, and controlled beta remains blocked only because the Era C row still needs 30-day SLO/uptime, ActivityStreams, and KPI proof. | Keep `pnpm launch:evidence:production`, `pnpm launch:review:production`, and `pnpm launch:beta:readiness` fresh with production env present; controlled beta can advance further once Era C has enough SLO, uptime, adoption, and KPI evidence or an explicit narrower beta acceptance policy is recorded. |\n| General public production | 6.5/10 | Not yet; product is feature-rich but evidence gates are red. | Passing 30-day SLO/uptime evidence, real KPI telemetry, and external activity-feed adoption proof. |\n| Institution-grade / 10/10 | 5.5-6/10 | Blocked by time-based evidence and real-world adoption. | At least 30 days of green SLO + uptime samples, 3 declared external feed consumers, and SOTA §26 KPI targets. |\n\n### Current SaaS Readiness\n\n| SaaS lane | Score | Current decision | Required next evidence |\n|---|---:|---|---|\n| Technical SaaS foundation | 7/10 | Strong enough to begin SaaS packaging: auth, roles, Postgres storage, provider ingestion, validation, docs, launch review, and trust/syndication tooling are real. | Complete staging secrets, production-like deployment, usage limits, tenant-aware data boundaries, and supportable onboarding. |\n| Paid pilot readiness | 8.2/10 | Close for 1-3 concierge pilots where Sun & Rain Works can manually onboard collections and invoice outside the app; `/pilot` is shared-nav reachable and publishes the offer, commercial-readiness ledger showing `0` paid pilots, manual invoice entitlement path, and in-app billing not built, named initial outreach queue, derived status ledger showing 13 researched accounts, 1 sent message, and 0 replies, and a zero-complete activation evidence ledger backed by managed outreach and activation events with the next required evidence. The queue includes Museum of New Zealand Te Papa Tongarewa, Museums Victoria, and Art Gallery of Ontario; Te Papa web-form outreach is recorded at `2026-07-04T18:30:00.000Z` from the user's reported July 4, 2026 11:30 AM Pacific submission, while no reply, invoice, or buyer activation is claimed. `pnpm pilot:buyer-pack` gives buyer-ready packs acceptance rows for outreach, invoice-backed entitlement, activation, support load, required KPIs, retention signal, gross-margin proof, and strict packet refresh, with the support-load row now verifying through `pnpm pilot:support -- --tenant <tenant-id> --summary`; `pnpm pilot:outreach`, `pnpm pilot:activation`, `pnpm pilot:support`, and `pnpm pilot:evidence --markdown` give operators validated no-JSON-edit commands for recording real first-outreach/milestone/support evidence and packaging explicit blocked/ready JSON plus Markdown evidence artifacts. `pnpm pilot:evidence --check` exits non-zero for blocked packets while still writing artifacts, so missing real entitlement, activation, support load after real pilot activity, KPI, retention, or gross-margin proof cannot pass automated readiness silently. Outreach replies require prior sent evidence, sent follow-up dates are barred from predating `sentAt`, activation milestones require prior same-tenant evidence, tenant-mismatched activation evidence is rejected, support response and resolution timestamps are barred from predating `openedAt`, existing support issue updates are barred from rewriting the original `requester`, `summary`, `openedAt`, or `severity`, already-resolved support issue updates are barred from rewriting `resolvedAt` or `resolutionSummary`, open support issues are barred from carrying resolution evidence, and support-load evidence remains blocked until an invoice-backed pilot has `pilot.support_minutes` evidence plus no open blocking or overdue support responses. `docs/ops/managed-linked-art-pilot-runbook.md` defines the concierge setup, tenant/source namespace, activation events, support intake, monthly evidence packet, and counter-backed route usage gate; `src/services/pilot-entitlements.ts`, `src/services/pilot-usage-counters.ts`, `src/services/pilot-support-issues.ts`, org storage scope, tenant preview scope, and route gates keep the manual pilot lane durable, org-aware, quota-gated, and exportable without implying self-serve billing readiness. | Follow up on Te Papa if they reply, sign one manual pilot scope, create an invoice-referenced entitlement, onboard one real pilot dataset using the runbook, attach deployment-specific security/legal evidence to the buyer packet, complete the buyer-pack acceptance rows with real tenant evidence, add route-level support-access implementation tests only if a support-as-customer feature ships, and complete activation, support, KPI, retention, and gross-margin ledgers with real tenant evidence. |\n| Self-serve SaaS readiness | 3/10 | Not ready; the app lacks pricing pages, tenant signup, billing, plan gates, org invites, usage dashboards, and support workflows. | Add account/org onboarding, billing/manual-plan entitlements, quotas, usage analytics, and customer success runbooks. |\n| Profitable SaaS business | 4/10 | The product has a credible technical wedge, but revenue operations and repeatable sales motion are not proven yet. | Convert paid pilots into recurring subscriptions with gross-margin, retention, support-load, and acquisition-channel evidence. |\n\nPilot packets now expose `commercial.billing`, `commercial.retention`, and `commercial.grossMargin` evidence directly. `pnpm review:goals` treats invoice-backed billing, `pilot.retention_signal_count`, and `pilot.gross_margin_percent` as selected checks, so managed-pilot readiness cannot pass from activation/support/KPI proof alone. `src/services/commercial-readiness-controls.ts` keeps the public pre-revenue copy, buyer-pack rows, invoice guard, monthly packet, and packaging gate in one executable report while real paid-pilot evidence remains missing.\n\n### SaaS Commercialization Strategy\n\n**Primary wedge:** managed Linked Art API + data-quality cockpit for small/mid-size museums, archives, galleries, digital humanities labs, and artist estates that want standards-compliant publication without hiring a semantic-web team. This wedge matches the current product surface best: provider ingestion, Linked Art normalization, API/docs, validation, public trust, AI query, reconciliation, IIIF, ActivityStreams, and Neon-backed storage.\n\n**Secondary wedge, defer until the B2B pilot loop works:** creator-side provenance and authorship tools. This may scale further, but it needs simpler onboarding, consumer-grade billing, evidence storage, and marketplace/export integrations that are not yet core to the current app.\n\n**Initial paid offer:** \"Managed Linked Art Launch Pilot\" — fixed-scope onboarding of one collection export into a hosted workspace, including data-quality report, Linked Art API, public browse pages, provenance/rights review flags, and a monthly evidence packet. Manual invoicing is acceptable for the first 1-3 concierge pilots; `pnpm pilot:packaging` now makes that support limit executable and blocks repeatable SaaS until subscription checkout, webhook entitlement sync, customer billing portal, and plan-change audit evidence exist.\n\n### SaaS Roadmap Track\n\n| Phase | Goal | Build / decide | Exit criteria |\n|---|---|---|---|\n| SaaS-0: Positioning + offer | Turn the technical platform into a sellable pilot. | ✅ `/pilot` now publishes the ICP, pilot promise, pricing hypothesis, deliverables, data prerequisites, support boundaries, success metrics, commercial-readiness ledger (`0` paid pilots, manual invoice path, in-app billing deferred), ten qualified prospect profiles, and a 13-account outreach queue with structured stages, status evidence, derived counts, three non-US prospects, and one recorded Te Papa web-form outreach. | Offer page is published, success metrics are explicit, named accounts are listed, and status tracking is visible; full exit now needs a reply or disqualification plus invoice-backed pilot proof. |\n| SaaS-1: Concierge paid pilot | Earn first non-demo revenue without overbuilding self-serve. | ✅ `docs/ops/managed-linked-art-pilot-runbook.md` now defines the pilot workspace setup runbook, tenant namespace convention, manual plan entitlement config, activation events, support intake process, customer evidence packet template, and `pnpm pilot:packaging` supportability check. Next: follow up only if Te Papa replies or the follow-up date arrives, then execute one invoice-backed pilot dataset with completed real-tenant activation milestones. | 1-3 invoice-backed paid pilots onboarded; each reaches first value within 7 days; pilot users can view/import/query/export without engineer intervention for routine tasks; packaging check remains supportable. |\n| SaaS-2: Multi-tenant product core | Make the app safe for multiple paying organizations. | ✅ Service-layer org-scoped storage isolation is in place for records, jobs, persisted AgentTask artifacts, researcher annotations, audit logs and org audit exports, ActivityStreams feed reads, activity readiness metrics, Postgres storage export, DR restore rehearsal, scoped public browse/derived reads, scoped AI/editorial read dependencies, wiki draft storage/access routes, wiki sync-map/reverse-ETL artifacts, authenticated org-session preview fallback for workspace pages, first-class managed `org-tenants.json` org/membership/invite backing, admin/team invite APIs, the `/orgs` operator UI, membership-validated `/api/orgs/active` cookie selection, workspace active-org status/selector/switch affordance plus stale-selection feedback, selected-org propagation through shared preview/storage/gate resolvers, records, wiki draft, annotation, AgentTask, and scoped AI/editorial route tenant RBAC read/write evidence, representative records/annotation/wiki draft/scoped AI-editorial non-member route RBAC evidence, non-admin org administration denial evidence, org-bound pilot entitlement/counter gates, and stable pilot API rate-limit denials, with Auth.js resolving active org memberships before compatibility env mappings. Support impersonation policy is now defined and test-locked in the procurement packet; next support-access evidence is route-level implementation proof only if the feature ships. | Tests prove tenant isolation at service and route boundaries; launch review includes tenant security checks; one hosted deployment supports multiple orgs without data bleed. |\n| SaaS-3: Billing + growth loop | Move from manual pilots to repeatable subscriptions. | ✅ Interim plan gates and durable manual pilot entitlement validation are executable in `src/services/pilot-entitlements.ts` and stored in managed `storage/pilot-entitlements.json`; `src/services/pilot-saas-packaging.ts` now decides when manual invoice billing is still enough and when subscription billing is required. Next: add pricing page, checkout or invoice-backed subscriptions, billing webhooks, usage enforcement, metered usage, trial/activation emails, onboarding checklist UI, churn/cancel reasons, and product analytics dashboard. | New org can sign up or be provisioned in under 15 minutes; MRR, activation, retention, support tickets, and usage are visible weekly; `pnpm pilot:packaging -- --target=repeatable-saas --check` passes. |\n| SaaS-4: Reliability + compliance for institutions | Make paid deployments procurement-friendly. | ✅ First procurement readiness packet is landed with security overview, data-flow diagram, hosting/subprocessor assumptions, backup/restore proof path, incident response summary, and checklist. Next: add customer-facing status page, SLA/SLO reporting, DPA/legal packet, access-review reports, deployment-specific backup evidence exports, incident drill evidence, and data-retention controls. | Controlled beta evidence is green enough for pilots; `pnpm review:goals:check` must be green before broad public SaaS claims. |\n| SaaS-5: Profitability gate | Prove the business model, not just the software. | Track gross-margin percentage, cloud cost per tenant, support minutes per account, onboarding cost, conversion rate, retention, expansion, and CAC/payback by channel. | Positive gross-margin per tenant, repeatable acquisition channel, retention evidence, and at least one pricing tier that remains profitable after support + infra cost. |\n\n### SaaS Product Backlog\n\n| Capability | Current state | SaaS-grade next step |\n|---|---|---|\n| Tenant/account model | Auth roles and Postgres storage exist; pilot entitlement/counter tests prove exact-tenant and org-bound gate isolation; `src/services/org-tenants.ts` stores first-class orgs, active/inactive memberships, and hashed-token invites in managed storage; `src/services/active-org-selection.ts` validates and persists selected active orgs for signed-in members and now shares that membership-validated resolver with request storage, preview, and route-gate scope; `src/services/org-session-status.ts` resolves sanitized active-org display state and generic stale-selection warnings; admin-only org APIs create/list orgs, memberships, sanitized invites, revocations, public invite acceptance, form posts, and org-scoped audit rows; `/orgs` provides the current operator UI for org creation, membership adds, invite creation, sanitized invite review, and pending-invite revocation; the workspace shell shows active org status, storage scope, membership role, accessible-org count, selector, stale-selection warning, and a switch/manage affordance without token material; Auth.js resolves active memberships into session org ids before compatibility env mappings; records, jobs, and persisted AgentTask artifacts support org-scoped service-layer storage under a shared root; tenant-tagged records, jobs, AgentTask, annotation, activity, audit, import, public browse/derived read routes, AI/editorial read routes, wiki draft access routes, wiki sync-map/reverse-ETL routes, and preview pages now propagate exact tenant or authenticated org scope into backing stores or read models. | Add route-level support-access implementation safeguards only if support-as-customer ships, plus broader tenant RBAC evidence before self-serve hosting. |\n| Plans and entitlements | `src/services/pilot-entitlements.ts` defines `free`, `pilot`, `institution`, and `enterprise` plan gates for imports, AI calls, storage, users, exports, API rate limits, and feature access; it also validates and persists interim manual pilot entitlement records by exact `tenantId` with optional `orgId` binding in managed `storage/pilot-entitlements.json`, evaluates requested usage against the active plan, and `src/services/pilot-route-gates.ts` reads tenant or selected authenticated-org usage from managed `storage/pilot-usage-counters.json` before provider facade import/search/profile, AI, content generation, records API, and records export work runs, returns stable `429`/`Retry-After` responses for API-per-minute overages, then records successful 2xx work back into the same counter ledger under the selected scope. `src/services/org-tenants.ts` now gives plan gates a first-class org/membership/invite backing store, `src/services/active-org-selection.ts` persists membership-validated org choice and feeds shared selected-org resolution into route gates, `src/services/org-session-status.ts` makes active-org scope visible in the workspace shell, while `proxy.ts` blocks tenant-tagged direct legacy provider routes, `src/auth/roles.ts` derives provider import write gates from the capability registry, scoped service storage covers records/jobs/AgentTask artifacts, records/jobs/AgentTask routes pass tenant identity into scoped stores, browse plus AI/editorial read APIs select scoped record stores when request context is scoped, wiki draft access routes select scoped draft stores, wiki sync-map/reverse-ETL routes select scoped stores, and preview pages select authenticated org records when query tenant scope is absent. | Add richer plan surfaces, production limiter metadata, and usage dashboards before supporting self-serve multi-org hosting. |\n| Billing | No in-app billing; `/pilot` now visibly says `0` paid pilots, manual invoice entitlement only, and in-app billing not built. First pilots have a durable manual invoice-backed entitlement contract with required invoice reference, namespace, owner, publication boundary, monthly evidence cadence, and Postgres export coverage, plus `pnpm pilot:buyer-pack` for generating the buyer-specific capture checklist and timestamped run artifact before packet creation; `/readiness` now surfaces that buyer handoff as its own waiting source until real buyer fields and invoice evidence arrive. | Use manual invoice entitlement records for pilots; graduate to Stripe or equivalent checkout/webhooks only after signed pilot pricing and activation evidence are validated. |\n| Onboarding | Developer-led setup works; the managed pilot runbook now defines concierge workspace setup, source-data requirements, namespace rules, and a seven-day activation checklist, but self-serve setup does not exist. | Execute the runbook on one real dataset, then add guided org setup, sample dataset path, first-value dashboard, and onboarding email flow. |\n| Usage analytics | Launch/exit evidence exists; GA4 page analytics is wired from the root layout when `NEXT_PUBLIC_GA_MEASUREMENT_ID` is set, with the current web stream ID `G-WPGJX5H0S7` documented for Vercel. The site now ships a browser-persisted analytics consent banner and privacy-choices control; Consent Mode v2 defaults deny ad storage, ad user data, ad personalization, and analytics storage until an analytics choice exists, advertising consent remains denied even when analytics is accepted, and `pnpm privacy:consent:check` writes `artifacts/privacy/analytics-consent-latest.json` proving GA4 ID validation, denied-by-default Consent Mode v2, persisted banner controls, `/privacy` disclosure, root-layout tag wiring, and the no-ad-personalization expansion guard. `src/services/pilot-outreach-events.ts`, `src/services/pilot-activation-events.ts`, `src/services/pilot-support-issues.ts`, `src/services/pilot-kpi-events.ts`, and `src/services/pilot-evidence-packet.ts` now record, summarize, and package required outreach/activation/support/KPI evidence, `pnpm pilot:outreach`, `pnpm pilot:activation`, `pnpm pilot:support`, `pnpm pilot:kpi`, and `pnpm pilot:evidence --markdown` give operators validated write/export paths for real JSON and customer-readable Markdown evidence, `/pilot` renders honest zero-sent and zero-complete ledgers until real records exist, and route-level entitlement gates read exact-tenant month/minute counters from managed storage and record successful gated route work, but broader tenant-aware activation analytics remain thin. | Implement tenant-aware tracking for activation milestones, validation improvements, customer views, weekly active users, usage cost, monthly evidence exports, and legal/CMP review before enabling ads, remarketing, or region-specific marketing workflows. |\n| Support operations | Technical docs are strong; the managed pilot runbook now defines support intake fields, severity levels, response rules, and evidence cadence for concierge pilots. | Formalize intake tooling, known-issues page, escalation policy, and pilot feedback cadence once the first pilot is active. |\n| Sales/marketing surface | `/pilot` now publishes the buyer-facing Managed Linked Art Launch Pilot page with problem, buyer, offer, pricing hypothesis, success metrics, support boundaries, source-network CTA, contact CTA, shared primary/footer nav access, named outreach queue, an outreach status ledger with non-clipped status cells, and a zero-complete activation evidence ledger backed by managed outreach/activation events plus operator commands needed to record and package real evidence. | Send/record the first real outreach, then add proof screenshots, completed activation milestones, and a customer evidence packet once the first pilot is active. |\n| Procurement readiness | `docs/ops/procurement-readiness-packet.md` now packages a buyer-reviewable security overview, Mermaid data-flow diagram, hosting/subprocessor assumptions, backup/restore evidence path, incident response summary, checklist, and explicit non-SOC-2 / incomplete-tenant-isolation limits. | Attach actual deployment-specific evidence, legal/DPA artifacts, access-review exports, incident drill evidence, and customer-specific subprocessors once the first pilot is active. |\n\n### Current Evidence Blockers\n\n| Era C exit check | Current evidence | Required to clear |\n|---|---|---|\n| SOTA §20.4 p95 SLOs | The current strict handoff reports `20/30` retained deployed SLO samples across `7/30` distinct UTC days, with `13/30` passing samples across `6/30` passing days and `7` failed/incomplete retained rows. `pnpm longterm:evidence:public` now reports SLO trend intake (`23` raw timestamped rows, `20` inside the report window, `3` older) plus distinct UTC observation days and acceptance rows so stale, clustered, old, or failed retained samples cannot masquerade as 30-day evidence. | Keep complete five-scenario `pnpm k6:slo` samples passing against the deployed target, then retain 30 days of passing samples; keep all p95s under policy thresholds until the SLO depth and failure-free acceptance rows are ready. |\n| Public-read uptime | Live public-read URL is known (`https://www.metamuseum.org`) and deployment preflight probes `/`, `/api/health`, and `/api/records` for launch-critical read availability; retained public-read uptime now has `117` probe snapshots across `9/30` observed UTC days, but availability is only `0.9744`, still below the 99.9% threshold because one retained failed sample remains. `pnpm monitoring:telemetry:public` forces a public probe snapshot, and `pnpm longterm:evidence:public` turns the uptime snapshot/history into both accumulation runway and maintenance repair artifacts with uptime depth, availability, and failed-sample age-out acceptance rows. | Keep scheduled public probes running via `METAMUSEUM_PUBLIC_READ_BASE_URL=https://www.metamuseum.org` / uptime envs; retain a clean 30-day window with >= 99.9% availability until the uptime observation-depth and availability rows are ready. |\n| Activity feed adoption | `3/3` declared external consumers in the latest local syndication artifact, with `metahistorybook-harvester-prod`, `daily-metahistorybook-prod`, and `wikidataexplorer-metamuseum-prod` filed from production reads; the restored `storage/activity-subscriptions.json` ledger now reports `3/3` matched durable external callbacks and `3` accepted callback rows. Single-consumer and three-consumer matrix proof tooling are available, `pnpm activity:partner-pack` writes the partner-specific `limit=100` read/subscription handoff plus per-consumer acceptance rows and a timestamped run artifact, now including the optional `type=Update -> linkedArt.id -> /api/events/...` dereference check; `/readiness` surfaces both broad community outreach and the waiting partner handoff as generated sources, and the no-ID pack includes three `pending-consumer-id` outreach slots while keeping `consumerIds: []` so placeholders cannot satisfy strict proof. `pnpm activity:community-outreach` captures broad Linked Art/Slack asks as outreach context with `strictEvidence: false`, prints the latest JSON, Markdown, and timestamped run artifact paths for attachment, and `/readiness` shows when its channel, message reference, timestamp, or owner still need to be captured. `/api/activity`, `/api/activity/collection`, and `/api/activity/page/{page}` record each declared consumer's observed `Create`/`Update`/`Delete` feed activity types, embedded `linkedArt.id` values now dereference through `/api/events/{encodedSourceActivityId}` with `_complete: false` plus source-preserving `equivalent[]`, `/api/records/{id}` now emits activity autodiscovery `Link` headers, `/api/providers/capabilities` advertises activity endpoint templates/filter/signing metadata, callback subscriptions can declare HMAC-SHA256 signing via secret references, `pnpm activity:adoption:matrix` plus the long-term runway/maintenance reports expose observed/missing type coverage, `pnpm activity:subscription:verify` records recent 2xx callback proof without hand-editing `storage/activity-subscriptions.json`, `pnpm activity:syndication:evidence` reports durable callback row counts, and `pnpm longterm:evidence:public` ignores placeholder-looking declared IDs in the long-term adoption runway. The first reviewed `Update` row is now live and partner-confirmed in production from a real Met object `437133` metadata delta; MetaHistoryBook also confirmed on `2026-07-10T00:18:38Z` that `/evidence`, `/api/evidence`, `/api/evidence/ledger`, and the Update row's hosted `/api/events/...` Linked Art dereference are externally live and conformant. `pnpm providers:coverage:seed` now verifies all `14/14` source-provider lanes before the tombstone scan, `pnpm activity:tombstone:scan` keeps the upstream tombstone watch fresh with provider-aware support/skipped/duplicate reporting, and `pnpm moma:dataset:diff` now provides a separate MoMA open-data snapshot comparison lane whose removals stay review-required and never satisfy ActivityStreams `Delete`. The latest run considered `126` stored records at `2026-07-10T01:07:06.186Z`, scanned `68` unique upstream targets across all `14` source providers, and found `0` upstream `404`/`410` tombstones. | Collect a real upstream `404`/`410` tombstone before emitting `Delete`, then send the second deploy-note for MetaHistoryBook to re-read `type=Delete`; keep all three callback verification rows fresh with `pnpm activity:subscription:verify`, publish retry/delivery guarantee windows, and capture refreshed `pnpm activity:adoption:matrix`, `pnpm providers:coverage:seed`, `pnpm activity:tombstone:scan`, `pnpm moma:dataset:diff` when a new MoMA snapshot is available, plus `pnpm activity:syndication:evidence` artifacts. |\n| SOTA §26 KPIs | Failing `reconciliationAutoApproveRate` and `reconciliationPrecisionReviewed`; local record-enrichment preview now passes after counting unique recognized authority references (`52/57`, `0.9123` against the `0.8` target), but it still must be regenerated from a production/postgres/warehouse records export before strict proof. AI query cost telemetry is sourced and within policy in the latest artifact. `pnpm monitoring:kpi-evidence` now creates the `monitoring/kpi-evidence.json` input from record-enrichment and reconciliation distribution counts, while `pnpm monitoring:kpi-evidence:production` requires Postgres storage, reviewed precision requires real reviewed/accepted auto-link counts plus a named production review source, acceptance rows distinguish production-shaped KPI inputs from local/current-environment exports, `diagnostics.blockers[]` names the exact observed value, Era C target, next evidence, command, and artifact for each KPI gap, `diagnostics.evidenceNeeds.enrichment.sampleRecordGaps[]` lists a capped repair sample of under-enriched record IDs plus existing recognized authority URIs and suggested Linked Art fields, `diagnostics.evidenceNeeds.reconciliation` now includes the raw candidate distribution plus a production `sourceReady` flag, `diagnostics.evidenceNeeds.reviewedPrecision` now includes a named-source readiness flag and source requirement, `diagnostics.capturePlan.rows[]` gives the production field/source checklist for enrichment, reconciliation distribution, reviewed precision, and strict refresh, and `diagnostics.handoffSummary` now reports both source-shape next evidence and `nextMetricCommand`/`nextMetricEvidenceNeeded` for the first KPI threshold blocker. `/readiness` and the `pnpm monitoring:kpi-evidence` console summary now lift the first repair target, suggested field, production source labels, raw candidate counts, and reviewed-source readiness so operators can triage the gap without opening raw JSON. | Export real production record-enrichment + reconciliation review counts to `monitoring/kpi-evidence.json`, make every KPI acceptance and capture row ready, clear `diagnostics.blockers[]`, confirm `diagnostics.handoffSummary.status` is `ready-to-refresh`, then rerun telemetry sync and Era C gates. |\n\n### Next Operating Plan\n\n1. **Deployment foundation** — ✅ preflight automation and runbook are landed (`pnpm launch:preflight`, `pnpm launch:preflight:production`, `docs/ops/deployment-preflight.md`); Neon-backed `DATABASE_URL` is seeded with all present managed storage documents, `DATABASE_URL` now verifies with `sslmode=verify-full`, `pnpm launch:smoke-token` now generates/rotates the staging researcher smoke token in `.env` without printing it, and the Next.js app is live at `https://www.metamuseum.org` on Vercel against Neon (`vercel.json`, `render.yaml`, `docs/deployment.md` landed; the close-out guard self-skips on Vercel). **Update 2026-07-03:** the rotated production `DATABASE_URL` is active, `/api/records` returns `200`, production preflight records no effective `METAMUSEUM_TEST_ROLE_OVERRIDE_TOKEN`, public base/SLO/IIIF metadata are set, validation and reconciliation Render `/health` probes pass, the active deployment is newer than the recorded secret rotation, and `pnpm launch:preflight:production` passes `20/20`. The full launch-evidence packet has been refreshed; strict readiness now waits on Era C real-world proof, not stale preflight data.\n2. **Evidence pipeline** — ✅ nightly workflow now prefers deployed-target `pnpm k6:slo`, seeds `/api/ai/query` telemetry, probes declared activity adoption, captures the public evidence-ledger live-probe packet, preserves local `pnpm k6:slo:ci` fallback, runs `pnpm longterm:evidence`, commits compact rolling k6/uptime/adoption/evidence-ledger inputs back to `main`, and uploads performance/activity/monitoring plus long-term runway artifacts; public-read uptime probe evidence is active but still needs 30 clean observation days.\n3. **Telemetry completeness** — ✅ AI query runs emit per-query usage/cost logs, and `pnpm monitoring:kpi-evidence:production` can now generate `monitoring/kpi-evidence.json` with aggregate production record-enrichment + reconciliation counts only when Postgres storage is active; still generate the real production export before the next exit-gate run.\n4. **External adoption proof** — ✅ partner/bot proof commands and runbook are landed (`pnpm activity:adoption:probe`, `pnpm activity:adoption:matrix`, `pnpm activity:community-outreach`, `pnpm activity:syndication:evidence`, `docs/ops/activity-adoption-proof.md`); the community outreach command records broad asks without turning them into strict proof, `/readiness` surfaces those rows as outreach context, and the syndication evidence command initializes an empty subscription ledger and reports durable callback rows without treating missing rows as proof. July 8 verification passed the provider tombstone-watch and local review-goals refresh, with strict ActivityStreams proof now blocked only on live `Delete` read coverage after real partner-confirmed `Update` and restored `3/3` durable callback rows. Keep validating `class: \"declared\"`, `declaredId`, `isExternal`, and recent `lastSeenAt` in `storage/activity-consumers.json`, then keep callback verification rows fresh for each counted consumer.\n5. **Launch review** — ✅ `pnpm launch:review` / `pnpm launch:review:production` aggregate latest preflight, exit-gate, security, DR, public-trust, a11y, and explore-smoke evidence into a packet, and `pnpm launch:beta:readiness` now summarizes controlled-beta go/no-go status from launch-review plus deployment-preflight artifacts. **Update 2026-07-04:** production is live on Vercel + Neon at `https://www.metamuseum.org`, the rotated production `DATABASE_URL` is active, `/api/records` returns `200`, `pnpm launch:preflight:production` passes `20/20` with explicit non-secret rotation metadata, full `pnpm launch:evidence:production` passes `8/9`, and `pnpm launch:review:production` passes `7/8`. Current launch status is governed by `pnpm review:goals:check`, which still reports external evidence required until Era C, long-term SLO/uptime, ActivityStreams, KPI, and pilot real-world blockers are green.\n6. **SaaS packaging** — ⚠️ `/pilot` is shared-nav reachable and publishes the Managed Linked Art Launch Pilot offer for concierge paid pilots, including pricing hypothesis, scope, prerequisites, support boundaries, success metrics, a commercial-readiness ledger that honestly shows 0 paid pilots, manual invoice entitlements, and in-app billing not built. The named outreach ledger now has 13 researched accounts, 1 sent message, and 0 replies: Te Papa web-form outreach was recorded at `2026-07-04T18:30:00.000Z` from the user's reported July 4, 2026 11:30 AM Pacific submission, while Museums Victoria and Art Gallery of Ontario remain researched prospects. `pnpm pilot:buyer-pack -- --submission-mode=form --omit-pricing` creates form-safe no-pricing outreach and a reply-ready packet with data checklist, seven-day timeline, sample outputs, and privacy/security notes, but the latest Te Papa pack still blocks until a real invoice reference exists. `pnpm pilot:outreach`, `pnpm pilot:activation`, `pnpm pilot:support`, `pnpm pilot:kpi`, and `pnpm pilot:evidence --markdown` convert real manual outreach, activation, support, KPI, entitlement, usage, retention, and gross-margin ledgers into explicit `blocked` or `ready` JSON plus Markdown packets while rejecting chronology errors, placeholder billing/KPI references, unsupported replies, and incomplete support states. The next SaaS evidence target is a Te Papa reply/follow-up or disqualification, then a signed invoice-referenced pilot and real tenant dataset with dated activation, support, KPI, retention, and gross-margin evidence; do not claim profitable SaaS readiness until recurring revenue, support load, retention, and gross-margin evidence are real.\n7. **Documentation currency** — ✅ every iteration must update `README.md` and `docs/roadmap.md` before `pnpm session:closeout`; `scripts/session-closeout.ts` enforces this on the normal closeout path by comparing both files to the previous closeout timestamp. Latest CI hardening keeps workflow JavaScript Actions on Node 24-native major versions while preserving the project’s Node 20 app execution path; latest UI polish keeps the home hero carousel in this current surface because clear full-color artwork imagery, attribution, reuse context, and a centered non-overlapping info panel are part of the public Linked Art trust contract.\n8. **Agent productionization** — ✅ persistent AgentTask review history is landed (`agent-tasks.json` managed storage + `/api/agents/tasks`), the internal AG2 bridge boundary is wired for Mercator/Janus behind `METAMUSEUM_AG2_BRIDGE_ENABLED`, and the local Python AG2 worker endpoint is available at `services/ag2-worker` with review-only contract tests, route-to-worker trace propagation, timeout/refusal fallback coverage, safe enablement docs, and live-worker eval artifacts via `pnpm ag2:worker:eval`. ⚠️ next value is collecting operator sign-off for any production bridge enablement; A2A/AG-UI remain deferred.\n\n---\n\n## Linked Art adherence uplift (current -> high)\n\nThis section turns the current medium/medium-high areas into explicit completion criteria.\n\n### A. Validation architecture depth (B2 follow-through)\n\nCurrent: validation architecture is in place and standards-linked.  \nTarget: high adherence through continuous standards-backed enforcement.\n\nAdherence upgrade target:\n- [x] ✅ Validation depth moved from \"in place\" to continuous fixture-backed drift enforcement.\n\nStatus:\n- [x] ✅ Complete.\n- [x] ✅ Evidence: `/explore` includes `vanda` source toggle and `/artwork/[id]` now exposes digital/IIIF manifest-image links when present in imported records.\n- [x] ✅ Provider/import transform policy is now executable via fixture manifest + tests:\n  - `tests/fixtures/validation/provider-fixture-manifest.json`\n  - `tests/quality/validation-architecture-depth.test.ts`\n- [x] ✅ Scheduled revalidation pass landed:\n  - `.github/workflows/validation-drift.yml` (weekly + manual dispatch)\n  - `scripts/validation-drift.ts`\n- [x] ✅ CI drift visibility + regression blocking landed:\n  - `.github/workflows/ci.yml` runs `pnpm validation:drift:check`\n  - net-new critical violations fail the job\n\nDefinition of done:\n- [x] ✅ Validation coverage includes object, digital, provenance, shared structures, and endpoint-shape fixtures from the reference rounds used in active slices.\n- [x] ✅ CI shows stable/no-regression validation trend for two consecutive release cycles.\n  - `config/validation-drift-cycles.json` tracks release-cycle snapshots.\n  - `pnpm validation:drift:trend` performs executable two-cycle no-regression gating.\n\n### B. Provider rollout completeness (B5)\n\nCurrent: all planned expansion providers are landed.  \nTarget: high adherence with repeatable, standards-mapped provider slices.\n\nAdherence upgrade target:\n- [x] ✅ Provider rollout discipline is locked to keep all landed B5 providers green with standards-mapped tests (fixtures + protocol/profile checks + parity checklist).\n\n- [x] ✅ Execute remaining providers as independent slices (Louvre, Harvard, Smithsonian, V&A, Princeton, Europeana, AIC, CMA), each with:\n  - [x] ✅ adapter isolation conformance\n  - [x] ✅ fixture-anchored standards mapping\n  - [x] ✅ protocol/profile checks from B8\n- [x] ✅ Track per-provider readiness in this roadmap with explicit `not started / in progress / done` status and standards round coverage.\n\nProvider readiness matrix:\n\n| Provider | Status | Standards round coverage | B8 protocol/profile checks | Notes |\n|---|---|---|---|---|\n| Rijks | done | object + digital + provenance + shared structures + endpoint-shape fixture anchors mapped to `LinkedArtModel1.0-Reference.md` | complete | Routes + adapter + tests are landed and included in provider protocol conformance suite. |\n| NGA | done | object + digital + provenance + shared structures + endpoint-shape fixture anchors mapped to `LinkedArtModel1.0-Reference.md` | complete | CSV ingest/provider slice landed with adapter + profile/search/import routes + tests. |\n| Louvre | done | object + shared structures + references fixture anchors mapped to `LinkedArtModel1.0-Reference.md` | complete | Routes + adapter + tests landed with provider facade wiring. |\n| Harvard | done | object + shared structures + endpoint-shape fixture anchors mapped to `LinkedArtModel1.0-Reference.md` | complete | Routes + adapter + tests landed with provider facade wiring. |\n| Smithsonian | done | object + shared structures + data-discovery fixture anchors mapped to `LinkedArtModel1.0-Reference.md` | complete | Routes + adapter + tests landed with provider facade wiring. |\n| V&A | done | object + digital + data-discovery fixture anchors mapped to `LinkedArtModel1.0-Reference.md` | complete | Routes + adapter + tests landed with provider facade wiring. |\n| Princeton | done | object + digital + shared structures fixture anchors mapped to `LinkedArtModel1.0-Reference.md` | complete | Routes + adapter + tests landed with provider facade wiring. |\n| Europeana | done | object + shared structures + data-discovery fixture anchors mapped to `LinkedArtModel1.0-Reference.md` | complete | Routes + adapter + tests landed with provider facade wiring. |\n| AIC | done | object + digital + shared structures fixture anchors mapped to `LinkedArtModel1.0-Reference.md` | complete | Routes + adapter + tests landed with provider facade wiring. |\n| CMA | done | object + digital + shared structures fixture anchors mapped to `LinkedArtModel1.0-Reference.md` | complete | Routes + adapter + tests landed with provider facade wiring. |\n\nProvider parity checklist (all must be complete per provider before status can be set to `done`):\n- [x] ✅ identity mapping (stable URI + `equivalent` handling)\n- [x] ✅ activity/event modeling preserved (no object-person shortcut regressions)\n- [x] ✅ rights/reuse + attribution semantics preserved and surfaced\n- [x] ✅ IIIF/link-layer handling preserved when source provides it\n- [x] ✅ source provenance metadata preserved end-to-end (`_source.provider`, source URL, ingest time)\n\nDefinition of done:\n- [x] ✅ All planned B5 providers shipped with route + adapter + tests + standards mapping notes.\n- [x] ✅ Provider parity checklist complete for identity, activity modeling, rights, IIIF, and source provenance.\n- [x] ✅ Local upstream metadata mirrors are organized under `data/source-repos/` with `moma-collection` and `tate-collection`\n      kept ignored from the main app repository except for the tracked pointer README; both are documented as\n      snapshot/open-data provider candidates rather than live public API or tombstone sources.\n- [x] ✅ MoMA is now wired as a snapshot/open-data provider: `src/adapters/moma-open-data.ts` reads local JSON/CSV,\n      maps `ObjectID` to `https://www.moma.org/collection/works/{ObjectID}`, maps artists by `ConstituentID` with\n      Wikidata/ULAN `equivalent[]`, preserves `Cataloged` quality status and conservative image policy in `_source`,\n      exposes `/api/moma/*` plus `/api/providers/moma/*`, and is explicitly excluded from live `404`/`410`\n      tombstone scans pending a separate dataset-diff deletion workflow. Provider note: [providers/moma-open-data.md](providers/moma-open-data.md).\n\n### C. HAL + Search relations conformance (rounds 71-79)\n\nCurrent: documented in the standards reference, partially deferred in platform slices.  \nTarget: high adherence with enforceable API behavior.\n\n- [x] ✅ Add conformance tests for OrderedCollection/OrderedCollectionPage search response shapes.\n- [x] ✅ Enforce stable relation naming and discoverability contracts via search relation fields (`nextPage` / `prevPage`) and HAL-aware protocol assertions.\n- [x] ✅ Prevent inverse-relationship duplication drift by asserting search-driven inverse discovery patterns.\n\nDefinition of done:\n- [x] ✅ Representative search endpoints pass relation + pagination + shape conformance tests.\n- [x] ✅ HAL link contract tests pass for versioning, related search links, and format/profile discoverability.\n\nStatus:\n- [x] ✅ `tests/quality/hal-search-relations-conformance.test.ts` enforces response-shape + relation-contract behavior on representative direct and provider-facade search routes.\n- [x] ✅ `tests/quality/protocol-conformance.test.ts` continues to enforce HAL separation + media-type/profile behavior on public API payloads.\n\n### D. Era B exit-gate closure readiness\n\nCurrent: Era B gate closed for the current scope.  \nTarget: keep it closed as new providers land.\n\n- [x] ✅ B6 authority-cache request-path policy enforced.\n- [x] ✅ B8/B9 conformance suites in CI.\n- [x] ✅ Postgres mode is now the default storage-of-record when `DATABASE_URL` is present.\n- [x] ✅ `storage/*.json` removed from version control.\n- [x] ✅ Write audit-log verification in CI for all primary write routes.\n\nDefinition of done:\n- [x] ✅ Era B exit gate lines are green with evidence links to tests and commands (`tests/quality/era-b-exit-gate.test.ts`, `tests/quality/protocol-conformance.test.ts`, `tests/quality/provider-protocol-conformance.test.ts`, `tests/quality/linked-art-b9-guardrails.test.ts`).\n\nAdherence upgrade target:\n- [x] ✅ Era B sustainment is continuously enforced: provider-slice conformance, authority-cache policy, and write-audit checks remain green as new sources land.\n\nExecution policy:\n- [x] ✅ No provider/validation PR merges without round + fixture-anchor standards mapping.\n- [x] ✅ No protocol-affecting merges without conformance test coverage for headers/shape/negotiation touched.\n- [x] ✅ Enforcement evidence:\n  - `.github/pull_request_template.md`\n  - `tests/quality/execution-policy-gates.test.ts`\n\n---\n\n## Stack decisions — locked in\n\n| Layer | Decision | Locked because |\n|---|---|---|\n| Framework | Next.js 16 App Router + RSC | already scaffolded; matches SOTA §11 |\n| UI lang | TypeScript 5, `strict: true` | scaffolded |\n| Styling | **Custom CSS** — design tokens + BEM-lite component classes in `app/globals.css`; no utility framework | user decision (reversed earlier Tailwind choice); resolves SOTA §30 Q3 |\n| Forms | React Hook Form + Zod | SOTA §3.2 |\n| Data fetching | RSC `fetch` first; TanStack Query for interactive client state | SOTA §11.3 + Next 16 cache-components model |\n| Server state mutations | Server Actions over fetch-based POSTs where possible | Next 16 idiom |\n| Tests | `node:test` + `node:assert` via `tsx`, Playwright for e2e, axe-core for a11y | SOTA §23 + legacy convention |\n| Pkg manager | pnpm | scaffolded |\n| Persistence (this era) | Postgres JSONB is the storage-of-record behind `src/utils/storage.ts` (`postgres` default with compatibility `file`/`double-write` modes) | preserves stable call sites during/after B3 migration |\n| Triple store (SOTA era) | **GraphDB (Ontotext)** — Community Edition for OSS path; SE/EE if SPARQL p95 demands | user decision; resolves SOTA §30 Q1 |\n| Search index (SOTA era) | **Solr 9** (LUX-aligned) | architecture decision (May 30, 2026); replaces Solr/OpenSearch fork |\n| Persistence (SOTA era) | Postgres 16 + JSONB · Solr 9 · GraphDB · pgvector | SOTA §3.4 / §8 with finalized search choice |\n| Curator backend (SOTA era) | **In-house curator console** (custom, Linked Art-native) | architecture decision (May 30, 2026); draws lessons from Arches/Ogee without adopting platform lock-in |\n| Developer/ops backend | **In-house ops console** (pipeline/debug/automation focused) | architecture decision (May 30, 2026); complements curator console |\n| Canonical ID scheme | **`https://lod.metamuseum.org/{type}/{ulid}`** | architecture decision (May 30, 2026); opaque, sortable, federation-ready |\n| Publication bridge (SOTA era) | **MediaWiki + custom Wikibase** for Meta Wiki Art publishing | aligns Linked Art/SPARQL/citation goals; see `docs/meta-wiki-art-bridge.md` |\n\n**Previously deferred architecture decisions (now finalized, May 30, 2026):**\n- [x] ✅ Search engine: **Solr 9** (LUX-aligned).\n- [x] ✅ Curator backend: **in-house custom curator console**.\n- [x] ✅ Developer backend: **in-house ops console**.\n- [x] ✅ Canonical ID scheme: **`https://lod.metamuseum.org/{type}/{ulid}`**.\n\n---\n\n\n## Era delivery history\n\nAll three delivery eras are complete (see Status above):\n\n- **Era A — The Lift** (10 PR-sized slices): TDD foundations, Met + Getty verticals, records/artworks/entities, Linked Art inspector, patterns/graph, issues/SSE, agents/jobs/content, workspace chrome.\n- **Era B — Hardening** (B1–B10): Zod contracts + schema versioning, formal validation, Postgres, auth + roles, 14-provider expansion, authority caching, exhibition/literature reconciliation, protocol + modeling guardrails, ARK conformance, gateway readiness.\n- **Era C — SOTA** (C1–C5): multi-modal storage + HAL, ETL + reconciliation + mapper, IIIF + visualizations, the AI layer, syndication + Meta Wiki Art + security/privacy hardening.\n\nThe full slice-by-slice and B-/C-series implementation detail is archived in **[progress/era-history.md](progress/era-history.md)**. The active forward plan is **[roadmap-to-10.md](roadmap-to-10.md)**.\n\n---\n## Cross-cutting standards (apply from Slice 1 onward)\n\nThese are not phases — they are continuous quality gates. Borrowed from `_legacy/AGENTS.md` and SOTA §23.\n\n- [x] ✅ **AIDD + TDD is the default.** Define behavior in natural language and map standards rounds/fixture anchors first, then write the failing test (red), pass with minimum code (green), and refactor with the suite green. Tests are the spec; reviewers read tests before reading implementation. A failing test stops the line. See [CLAUDE.md](../CLAUDE.md) §\"We lead with AIDD + TDD\".\n- [x] ✅ **Adapters do not import each other.** Bridge via `src/utils/artwork-builder.ts`.\n- [x] ✅ **Contracts are leaf modules.** No upstream deps.\n- [x] ✅ **`_source.raw` is immutable.** Transform at read time.\n- [x] ✅ **Rights-aware by default.** Every UI surface showing an image carries reuse status + attribution.\n- [x] ✅ **Linked Art JSON-LD is the canonical data layer.** UI DTOs (`Artwork`) are separate; map at the boundary.\n- [x] ✅ **Loading / empty / error / success states** on every interactive UI.\n- [x] ✅ **Keyboard navigation + visible focus** on every interactive surface.\n- [x] ✅ **At least one test for any risky transform.**\n- [x] ✅ **Cite or refuse.** Generated content always carries citations + rights + review state.\n- [x] ✅ **Next 16 specifics**: `cookies()`, `headers()`, dynamic `params` are async — always `await` them.\n- [x] ✅ **No `unknown` swallowed silently.** A record with unknown rights gets an explicit \"Rights unknown — do not reuse\" badge.\n- [x] ✅ **Reference-driven conformance.** Any provider/API/schema/search/protocol PR must cite relevant [linked-art/LinkedArtModel1.0-Reference.md](linked-art/LinkedArtModel1.0-Reference.md) rounds and include failing-first tests mapped to the referenced fixture anchors.\n- [x] ✅ **Reference maintenance loop.** If a PR depends on newly published Linked Art guidance not yet captured in `LinkedArtModel1.0-Reference.md`, that round/addendum must be appended before (or in the same change as) the implementation PR.\n- [x] ✅ **Standards Mapping is required in provider/validation PRs.** Include: referenced round numbers, fixture anchors exercised, and failing-first test files proving red→green conformance.\n- [x] ✅ **PR template completion is required.** Every PR must complete [.github/pull_request_template.md](../.github/pull_request_template.md), including AIDD checklist gates, standards mapping, and protocol assertions touched.\n- [x] ✅ **AI-generated tests/refactors require human semantic verification.** AI can accelerate drafting, but authors/reviewers remain accountable for Linked Art correctness, provider semantics, and protocol behavior.\n- [x] ✅ **Provider/pipeline boundary drift is actively bounded.** `docs/risk-register.md` tracks risk posture and `tests/contracts/provider-boundary-contracts.test.ts` enforces adapter import boundaries.\n- [x] ✅ **Protocol conformance is mandatory.** Public API behavior must preserve JSON-LD context/profile correctness, support `GET` + `OPTIONS`, and provide baseline CORS + media-type negotiation.\n- [x] ✅ **AI-RSI compounding loop is mandatory.** Each merge requires: 72h review check, evidence capture in session log, and roadmap/README/CLAUDE updates before the next RSI expansion scope.\n- [x] ✅ **HAL/data separation is mandatory.** API navigation metadata lives in `_links` (non-semantic) and must not pollute semantic graph payloads.\n- [x] ✅ **URI opacity is mandatory.** Never infer semantics from URI path structure in router logic or client helpers.\n- [x] ✅ **Inverse discovery via Search API.** Prefer standardized search relations and OrderedCollection/OrderedCollectionPage responses rather than duplicating inverse relationship fields.\n- [x] ✅ **Carrier/content separation is non-negotiable.** `HumanMadeObject`/`DigitalObject` must remain distinct from `VisualItem`/`LinguisticObject`.\n- [x] ✅ **Authority-backed classification UX.** Curatorial/classification input paths must use controlled authority sources (AAT/ULAN/Wikidata equivalents), not free-text categories by default.\n- [x] ✅ **Data discovery signposting.** Public record HTML pages expose a single canonical `describedby` link to the Linked Art JSON-LD record.\n\nVerification note (May 31, 2026):\n- The first nine cross-cutting gates above are marked complete based on current enforcement in CI/tests and live implementation patterns (provider boundary checks, contract leaf structure, `_source.raw` invariants, rights surfaces, Linked Art boundary mapping, interactive state handling, and keyboard/focus coverage).\n- Additional governance/protocol gates are marked complete where enforced by executable tests (`protocol-conformance`, `provider-protocol-conformance`, `hal-search-relations-conformance`, `provider-digital-content-gates`) and PR governance checks (`execution-policy-gates`, PR template standards mapping requirements).\n- Remaining open gates in this section are intentionally left unchecked only where future era scope is intentionally deferred; cross-cutting gate set above is now fully enforced in current Era A/B surfaces.\n\n---\n\n## What this roadmap deliberately does NOT do (yet)\n\nTo stay honest about scope:\n\n- [x] ✅ **No microservice split during Era A.** All routes lived in the single Next 16 app; Python services begin in Era B (validation) and Era C (reconciliation, AI).\n- [x] ✅ **No triple store or vector store in Era A or B.** Postgres + JSONB remains sufficient until Era C search/graph patterns are activated.\n- [x] ✅ **No module-federation for the Era A app.** The app remains a single deployable Next.js build.\n- [x] ✅ **No Arches / Ogee / Zelge adoption planned.** Lessons are reused, but curator and ops surfaces remain in-house.\n- [x] ✅ **No fancy IIIF in Era A.** Current Era A/B UI uses provider image URLs; OpenSeadragon remains planned for C3.\n- [x] ✅ **No NL→SPARQL until the SHACL gate exists** (B2 → C4).\n- [x] ✅ **No Meta Wiki Art write path** until contracts, validation, auth, audit log, and Postgres cutover are stable (C5).\n\nVerification note (May 31, 2026):\n- Constraints above are verified against current code/routes/dependencies and remain in force for pre-Era-C scope control.\n\n---\n\n## What I'd build next, concretely\n\nEra C1 prep while sustaining Era B quality gates:\n- [x] ✅ **RSI-5: AI evidence drift + citation freshness** (Medium-severity remediation) is complete (proven 2026-06-09):\n  - Owner: Platform + AI Reliability\n  - **Action 1 complete (2026-06-09):** `/api/ai/query` now returns citation metadata, coverage, and explicit refusal state, locked by `tests/api/ai-query.test.ts` and `tests/quality/cite-or-refuse-conformance.test.ts`.\n  - **Action 2 complete (2026-06-09):** `/api/ai/query` and `/api/ai/chat` now emit `retrievedAt` + `citationFreshness` diagnostics and refuse stale evidence via policy-backed route tests.\n  - Scope:\n    - Enforce same cite-or-refuse behavior beyond `/api/ai/chat` so `/api/ai/query` emits stable evidence metadata and refuses under coverage/freshness thresholds.\n    - Keep `/api/ai/chat` grounded response semantics while adding the shared freshness guard.\n  - Acceptance:\n    - `/api/ai/query` returns `{ answer, citations, coverage, citationFreshness, refusalReason? }` with `entityId`, `propertyPath`, `sourceUrl`, and `retrievedAt` in cited outputs.\n    - Under-cited or stale-evidence answers return explicit refusal and reason.\n    - Regression test coverage proves chat/query parity and stale-evidence failure modes.\n  - Proof packet:\n    - `tests/api/ai-query.test.ts`, `tests/api/ai-chat.test.ts`, and `tests/quality/cite-or-refuse-conformance.test.ts` cover cited success, coverage refusal, and freshness refusal behavior.\n    - Close-out packet synchronizes `docs/risk-register.md`, `CLAUDE.md`, `README.md`, and this roadmap with evidence proofs.\n- [x] ✅ **RSI-6: AI eval drift baselines include citation freshness** (Medium-severity remediation) is complete (proven 2026-06-09):\n  - `src/services/ai-eval-harness.ts` now scores `citationFreshness` from actual citation/source timestamps instead of treating retrieval time as always fresh.\n  - `src/services/ai-eval-regression.ts`, `scripts/ai-eval-gate.ts`, and `config/ai-eval-regression-policy.json` now baseline, persist, print, and fail-fast on `citationFreshnessDrop`.\n  - `evals/golden-museum-questions.v1.json` and `docs/evals/golden-museum-questions.md` now declare `citationFreshnessThreshold = 0.95`.\n  - Proof packet: `tests/services/ai-eval-harness.test.ts`, `tests/services/ai-eval-regression.test.ts`, `tests/services/ai-eval-artifacts.test.ts`, `tests/quality/ai-eval-golden-dataset.test.ts`, plus direct AI eval gate output with `citationFreshness=1` and `citationFreshnessDrop=0`.\n- [x] ✅ **RSI-7: AI eval summary badges + aging-pressure alerting** (Medium-severity remediation) is complete (proven 2026-06-09):\n  - `src/services/ai-eval-artifacts.ts` now renders `artifacts/evals/summary.md` with status, faithfulness, relevance, citation accuracy, `citationFreshness`, pass-rate badges, artifact links, and alerts.\n  - `src/services/ai-eval-harness.ts` now persists citation freshness aging (`oldestAgeDays`, `oldestAgeRatio`, `maxAgeDays`) for trend-aware pressure detection.\n  - `.github/workflows/ai-eval-gate.yml` now appends the summary to `$GITHUB_STEP_SUMMARY` and uploads `artifacts/evals/` for CI inspection.\n  - Proof packet: `tests/services/ai-eval-artifacts.test.ts`, plus direct AI eval gate output with `summary=artifacts/evals/summary.md`, `citationFreshness=1`, and `oldestAgeRatio=0`.\n- [x] ✅ **RSI-8: AI eval artifact dashboard visibility** (Medium-severity remediation) is complete (proven 2026-06-09):\n  - `src/services/ai-eval-dashboard.ts` now loads ignored local eval artifacts, latest metrics, trend runs, artifact timestamps, and freshness-aging warnings with explicit empty/partial states.\n  - `app/(workspace)/ai-evals/page.tsx` now provides a read-only app dashboard for latest eval summary, trend index, freshness-aging state, and active warnings.\n  - Navigation now exposes the dashboard from the workspace sidebar, primary Workspace menu, and footer.\n  - Proof packet: `tests/services/ai-eval-dashboard.test.ts` and `tests/pages/ai-evals-page.test.ts`, plus focused system Node test output passing 3 tests.\n- [x] ✅ **RSI-9: latest-vs-previous AI eval artifact diff** (Medium-severity remediation) is complete (proven 2026-06-09):\n  - `src/services/ai-eval-dashboard.ts` now computes latest-vs-previous metric deltas, freshness-aging pressure deltas, status changes, prompt-count changes, identity changes, and compact “what changed” notes.\n  - `app/(workspace)/ai-evals/page.tsx` now renders a “Latest vs previous run” review section with metric arrows, freshness pressure movement, and fast-review notes.\n  - Proof packet: `tests/services/ai-eval-dashboard.test.ts` and `tests/pages/ai-evals-page.test.ts`, plus focused system Node test output passing 3 tests.\n- [x] ✅ **RSI-10: severity-labeled AI eval diff triage** (Medium-severity remediation) is complete (proven 2026-06-09):\n  - `src/services/ai-eval-dashboard.ts` now classifies metric deltas, freshness-aging pressure movement, and overall latest-vs-previous diff priority as `regression`, `watch`, `stable`, or `improved`.\n  - `app/(workspace)/ai-evals/page.tsx` now renders priority labels and visible metric/aging threshold pills so review starts with severity instead of raw deltas only.\n  - Proof packet: `tests/services/ai-eval-dashboard.test.ts` and `tests/pages/ai-evals-page.test.ts`, plus focused system Node output passing 3 tests, `pnpm test` passing 787/249, `pnpm lint` passing with one existing warning, and production Next build passing via system Node.\n- [x] ✅ **RSI-11: policy-driven AI eval priority visibility** (Medium-severity remediation) is complete (proven 2026-06-09):\n  - `config/ai-eval-regression-policy.json` now owns diff severity thresholds consumed by dashboard and CI summary generation.\n  - `app/(workspace)/ai-evals/page.tsx` now shows last-N severity distribution across `regression`, `watch`, `stable`, and `improved` comparisons.\n  - `artifacts/evals/summary.md` now includes CI-visible review priority when at least two retained eval runs exist.\n  - Proof packet: `tests/services/ai-eval-dashboard.test.ts`, `tests/services/ai-eval-artifacts.test.ts`, and `tests/pages/ai-evals-page.test.ts`, plus focused system Node output passing 8 tests, `pnpm test` passing 788/249, `pnpm lint` passing with one existing warning, AI eval gate printing `reviewPriority: stable`, and production Next build passing via system Node.\n- [x] ✅ **RSI-12: AI eval agent-summary reliability** (Medium-severity remediation) is complete (proven 2026-06-09):\n  - `src/services/ai-eval-severity.ts` now validates `diffSeverityPolicy` shape/order and fails malformed policy with explicit errors.\n  - `/api/ai-evals/summary` now exposes agent-ready JSON with latest run, review priority, severity distribution, severity history, alerts, and artifact links.\n  - `app/(workspace)/ai-evals/page.tsx` now renders compact severity sparkline and latest-vs-previous comparison history for fast trend review.\n  - Proof packet: `tests/services/ai-eval-severity.test.ts`, `tests/api/ai-evals-summary.test.ts`, `tests/services/ai-eval-dashboard.test.ts`, `tests/services/ai-eval-artifacts.test.ts`, and `tests/pages/ai-evals-page.test.ts`, plus focused system Node output passing 13 tests, `pnpm test` passing 793/251, `pnpm lint` passing with one existing warning, AI eval gate printing `reviewPriority: stable`, and production Next build confirming `/api/ai-evals/summary`.\n- [x] ✅ **RSI-13: AI eval contract + CI annotation reliability** (Medium-severity remediation) is complete (proven 2026-06-09):\n  - `src/contracts/zod/ai-eval-summary.ts` now defines the reusable agent JSON contract and OpenAPI schema for `/api/ai-evals/summary`.\n  - `config/ai-eval-regression-policy.json` now owns `severityHistoryPolicy.maxComparisons`, which drives dashboard distribution/history and agent JSON window metadata.\n  - `scripts/ai-eval-gate.ts` now emits a GitHub PR warning annotation when review priority is `watch` or `regression`, with workflow path filters covering `/api/ai-evals`, policy, and contract changes.\n  - Proof packet: `tests/api/ai-evals-summary.test.ts`, `tests/api/openapi.test.ts`, `tests/services/ai-eval-severity.test.ts`, `tests/services/ai-eval-dashboard.test.ts`, `tests/services/ai-eval-artifacts.test.ts`, and `tests/pages/ai-evals-page.test.ts`, plus focused system Node output passing 18 tests, `pnpm test` passing 796/251, `pnpm lint` passing with one existing warning, AI eval gate printing `reviewPriority: stable`, and production Next build confirming `/api/ai-evals/summary`.\n- [x] ✅ **RSI-14: AI eval version/pruning hygiene** (Medium-severity remediation) is complete (proven 2026-06-09):\n  - `/api/ai-evals/summary` now returns `schemaVersion: 1`, and `aiEvalSummaryResponseSchema` rejects unsupported versions before agents consume the payload.\n  - `docs/evals/golden-museum-questions.md` publishes exact GitHub CI annotation examples for `regression` and `watch`, with snapshot assertions keeping docs and formatter output aligned.\n  - `src/services/ai-eval-artifacts.ts` now prunes orphaned run JSON outside the retained trend window while preserving retained run files and non-JSON notes.\n  - Proof packet: `tests/api/ai-evals-summary.test.ts`, `tests/api/openapi.test.ts`, and `tests/services/ai-eval-artifacts.test.ts`, plus focused system Node output passing 22 tests, `pnpm test` passing 800/251, `pnpm lint` passing with one existing warning, AI eval gate printing `reviewPriority: stable`, and production Next build confirming `/api/ai-evals/summary`.\n- [x] ✅ **RSI-15: AI eval migration/reporting visibility** (Medium-severity remediation) is complete (proven 2026-06-09):\n  - `src/contracts/zod/ai-eval-summary.ts` now includes future `schemaVersion: 2` migration notes, with v1 accepted and planned v2 rejected through fixture compatibility tests.\n  - `src/services/ai-eval-artifacts.ts` now returns a retention pruning report with `delete`/`dry-run` mode and retained/orphaned/deleted/preserved file counts.\n  - `artifacts/evals/summary.md` now surfaces latest CI annotation status and retention pruning status for PR/build reviewers.\n  - Proof packet: `tests/api/ai-evals-summary.test.ts`, `tests/services/ai-eval-artifacts.test.ts`, and `tests/fixtures/ai-eval-summary/*`, plus focused system Node output passing 24 tests, `pnpm test` passing 802/251, `pnpm lint` passing with one existing warning, AI eval gate printing `reviewPriority: stable`, and production Next build confirming `/api/ai-evals/summary`.\n- [x] ✅ **RSI-16: AI eval summary artifact/schema visibility** (Medium-severity remediation) is complete (proven 2026-06-09):\n  - `tests/fixtures/ai-eval-summary/summary-snapshot.md` now locks the generated CI summary markdown, proving `summary.md` stays reviewable and stable.\n  - `/api/ai-evals/summary` now exposes the latest `retentionPruneReport` for agents, including delete/dry-run mode and retained/orphaned/deleted/preserved counts.\n  - `/api/openapi` now includes the AI eval summary schema migration compatibility table so future `schemaVersion` upgrades are discoverable from the contract surface.\n  - Proof packet: `tests/api/ai-evals-summary.test.ts`, `tests/api/openapi.test.ts`, `tests/services/ai-eval-artifacts.test.ts`, `tests/services/ai-eval-dashboard.test.ts`, and `tests/fixtures/ai-eval-summary/summary-snapshot.md`, plus focused system Node output passing 25 tests, `pnpm test` passing 803/251, `pnpm lint` passing with one existing warning, AI eval gate printing `reviewPriority: stable`, and production Next build confirming `/api/ai-evals/summary`.\n- [x] ✅ **RSI-17: Visual ETL Mapper AI-assist safety** (Medium-severity remediation) is complete (proven 2026-06-09):\n  - `/api/ai/mapping-assist` now returns review-ready, contract-valid `MappingTemplate` drafts from source columns with confidence, rationale, standards anchors, and unmapped-column diagnostics.\n  - `/etl/mapper` now exposes a \"Suggest mapping with AI\" action while keeping generated mappings review-only before any ingestion activation.\n  - Unknown columns are surfaced as diagnostics instead of invented mappings.\n  - Proof packet: `tests/services/mapping-assist.test.ts`, `tests/api/ai-mapping-assist.test.ts`, `tests/components/etl-mapper-config.test.ts`, and `tests/api/openapi.test.ts`, plus focused system Node output passing 7 mapper-assist tests and 2 OpenAPI tests, `pnpm test` passing 809/253, `pnpm lint` passing with one existing warning, AI eval gate printing `reviewPriority: stable`, and production Next build confirming `/api/ai/mapping-assist`.\n- [x] ✅ **RSI-18: mapper-assist fixture/schema/importability hardening** (Medium-severity remediation) is complete (proven 2026-06-09):\n  - `tests/fixtures/mapping-assist/tricky-columns.json` now locks tricky rights/credit/sensitive columns so mapper assist cannot invent unsafe Linked Art target paths.\n  - `src/utils/etl-mapper-assist.ts` and `/etl/mapper` now support importing returned suggestions as reviewable ReactFlow draft nodes/edges.\n  - `/api/openapi` now exposes `MappingAssistResponse` and references it from `/api/ai/mapping-assist`.\n  - Proof packet: `tests/services/mapping-assist.test.ts`, `tests/utils/etl-mapper-assist.test.ts`, `tests/components/etl-mapper-config.test.ts`, `tests/api/openapi.test.ts`, and `tests/api/ai-mapping-assist.test.ts`, plus focused system Node output passing 11 tests, `pnpm test` passing 811/254, `pnpm lint` passing with one existing warning, AI eval gate printing `reviewPriority: stable`, and production Next build confirming `/api/ai/mapping-assist`.\n- [x] ✅ **RSI-19: provider-family/browser/request-schema mapper hardening** (Medium-severity remediation) is complete (proven 2026-06-09):\n  - `tests/fixtures/mapping-assist/provider-families.json` now covers Met, Getty, and Rijks-style mapper columns with allowed-path and must-stay-unmapped assertions.\n  - `scripts/smoke-etl-mapper-assist.ts` and `pnpm smoke:etl:mapper-assist` now provide a Playwright browser smoke for `/etl/mapper` assist generation plus draft import.\n  - `/api/openapi` now exposes `MappingAssistRequest` and attaches it to the `/api/ai/mapping-assist` POST request body.\n  - Proof packet: `tests/services/mapping-assist.test.ts`, `tests/scripts/etl-mapper-smoke-script.test.ts`, and `tests/api/openapi.test.ts`, plus focused system Node output passing 7 tests, `pnpm smoke:etl:mapper-assist` passing against `http://localhost:3001/en`, `pnpm test` passing 813/255, `pnpm lint` passing with one existing warning, AI eval gate printing `reviewPriority: stable`, and production Next build confirming `/api/ai/mapping-assist`.\n- [x] ✅ **RSI-20: negative mapper fixtures, visual screenshot, and API-doc examples** (Medium-severity remediation) is complete (proven 2026-06-09):\n  - `tests/fixtures/mapping-assist/negative-provider-families.json` now locks near-miss Met/Getty/Rijks columns so rights, credit, restriction, sensitivity, donor, and flag wording cannot trigger unsafe suggestions.\n  - `scripts/smoke-etl-mapper-assist.ts` now waits on the mapping-assist POST, imports the draft, and writes `artifacts/smoke/etl-mapper-assist-imported.png` with animations disabled.\n  - `/api/docs` now includes concrete mapping-assist request and response examples next to the Swagger UI entry point.\n  - Proof packet: `tests/services/mapping-assist.test.ts`, `tests/scripts/etl-mapper-smoke-script.test.ts`, and `tests/api/docs.test.ts`, plus focused system Node output passing 11 tests, `pnpm smoke:etl:mapper-assist` passing against `http://localhost:3001/en`, `pnpm test` passing 814/255, `pnpm lint` passing with one existing warning, AI eval gate printing `reviewPriority: stable`, and production Next build passing.\n- [x] ✅ **RSI-21: mapper layout, OpenAPI-sourced docs examples, and confidence policy** (Medium-severity remediation) is complete (proven 2026-06-09):\n  - `app/globals.css` now gives mapper actions a full-width wrapped row with no button overlap in the refreshed screenshot.\n  - `app/api/docs/route.ts` now renders mapping-assist request/response examples from `/api/openapi` instead of duplicating static JSON.\n  - `src/services/mapping-assist.ts` now applies a minimum confidence policy so lower-confidence accession/place/description patterns stay diagnostics-only.\n  - Proof packet: `tests/components/etl-mapper-config.test.ts`, `tests/api/docs.test.ts`, and `tests/services/mapping-assist.test.ts`, plus focused system Node output passing 15 tests, `pnpm smoke:etl:mapper-assist` refreshing `artifacts/smoke/etl-mapper-assist-imported.png`, `pnpm test` passing 817/255, `pnpm lint` passing with one existing warning, AI eval gate printing `reviewPriority: stable`, and production Next build passing.\n- [x] ✅ **RSI-22: public source narrative and trust uplift** (Medium-severity remediation) is complete (proven 2026-06-09):\n  - `app/datasets/page.tsx` now presents a public source-network narrative backed by `getProviderCapabilities`, not copied prototype constants.\n  - `app/about/page.tsx` and `app/projects/page.tsx` now migrate the sibling `meta-museum-art` mission/project surfaces into native Next pages while replacing coming-soon/static project cards with live source-network, Linked Art workbench, and Meta Wiki Art workflow links.\n  - `src/services/site-metadata.ts` centralizes OpenGraph/Twitter metadata with a reviewed local image, and footer navigation exposes Contact/Privacy/Terms plus asset provenance.\n  - `docs/asset-provenance.md` tracks all preserved sibling visual assets with SHA-256 hashes while marking placeholder thumbnails as excluded from public use and keeping copied legal text out.\n  - Proof packet: `tests/services/public-source-narrative.test.ts`, `tests/pages/public-source-pages.test.ts`, focused RSI-22 test output passing 6/2 plus follow-up `pnpm test -- tests/pages/public-source-pages.test.ts` passing 851/267 on 2026-06-09, `pnpm lint` passing with one existing warning, `pnpm build` passing, and screenshot proof at `artifacts/smoke/datasets-page.png`.\n- [x] ✅ **RSI-23: public-source agent API and trust smoke hardening** (Medium-severity remediation) is complete (proven 2026-06-09):\n  - `/api/public-sources/summary` now exposes schema-versioned agent JSON for source stats, provider capability flags, and imported asset provenance.\n  - `docs/asset-provenance.md` and `src/contracts/zod/public-sources-summary.ts` now enforce explicit license-review statuses so unknown asset rows fail.\n  - `pnpm smoke:public-trust` captures browser screenshots for `/datasets`, `/contact`, `/privacy`, and `/terms`; the nested `meta-museum-art` prototype copy was removed after all images were preserved and inventoried.\n  - Proof packet: `tests/api/public-sources-summary.test.ts`, `tests/services/public-source-narrative.test.ts`, `tests/scripts/public-trust-smoke-script.test.ts`, focused RSI-23 output passing 6/3, `pnpm smoke:public-trust` passing against `http://localhost:3001`, `pnpm test` passing 827/259, `pnpm lint` passing with one existing warning, and `pnpm build` passing.\n- [x] ✅ **RSI-24: OpenAPI, checksum drift, and screenshot retention hardening** (Medium-severity remediation) is complete (proven 2026-06-09):\n  - `/api/openapi` now includes `PublicSourcesSummaryResponse` and references it from `/api/public-sources/summary`.\n  - Imported public-source assets now fail tests when their SHA-256 hashes drift from `docs/asset-provenance.md`.\n  - `pnpm smoke:public-trust` now writes timestamped screenshot runs, latest copies, previous-run links, a summary JSON, and prunes old runs outside the retention window.\n  - Proof packet: `tests/api/openapi.test.ts`, `tests/services/public-source-narrative.test.ts`, `tests/services/public-trust-smoke-artifacts.test.ts`, `tests/scripts/public-trust-smoke-script.test.ts`, focused RSI-24 output passing 6/5, `pnpm smoke:public-trust` passing against `http://localhost:3001`, `pnpm test` passing 828/260, `pnpm lint` passing with one existing warning, and `pnpm build` passing.\n- [x] ✅ **RSI-25: public trust docs, diff metadata, and CI artifact visibility** (Medium-severity remediation) is complete (proven 2026-06-09):\n  - `/api/docs` now renders the `/api/public-sources/summary` response example from `/api/openapi`, keeping examples single-source for humans and agents.\n  - Public trust smoke artifacts now include latest-vs-previous checksum/byte diff metadata per screenshot plus CI-ready summary markdown.\n  - `.github/workflows/public-trust-smoke.yml` now builds, runs `pnpm smoke:public-trust`, appends public trust summary links to `$GITHUB_STEP_SUMMARY`, and uploads `public-trust-smoke-artifacts`.\n  - Proof packet: `tests/api/docs.test.ts`, `tests/api/openapi.test.ts`, `tests/services/public-trust-smoke-artifacts.test.ts`, `tests/services/public-trust-smoke-ci-summary.test.ts`, `tests/scripts/public-trust-smoke-script.test.ts`, `tests/scripts/public-trust-ci-workflow.test.ts`, focused RSI-25 output passing 12/10, `pnpm smoke:public-trust` passing against temporary `http://localhost:3001`, `pnpm test` passing 830/262, `pnpm lint` passing with one existing warning, and `pnpm build` passing.\n- [x] ✅ **RSI-26: pixel-diff thresholds, public trust summary API, and main CI artifact links** (Medium-severity remediation) is complete (proven 2026-06-09):\n  - `pnpm smoke:public-trust` now decodes PNG screenshots, computes changed-pixel ratios, and fails when `PUBLIC_TRUST_SCREENSHOT_PIXEL_DIFF_THRESHOLD` is exceeded.\n  - `/api/public-trust/summary` now exposes schema-versioned latest public trust smoke artifacts and pixel-diff status for agents.\n  - `.github/workflows/ci.yml` now runs public trust smoke, appends summary links to `$GITHUB_STEP_SUMMARY`, and uploads `public-trust-smoke-artifacts`.\n  - Proof packet: `tests/services/public-trust-smoke-artifacts.test.ts`, `tests/api/public-trust-summary.test.ts`, `tests/api/openapi.test.ts`, `tests/scripts/public-trust-smoke-script.test.ts`, `tests/scripts/public-trust-ci-workflow.test.ts`, focused RSI-26 output passing 10/7, `pnpm smoke:public-trust` passing with `unchanged=4` and `pixel failures=0`, `pnpm test` passing 834/263, `pnpm lint` passing with one existing warning, and `pnpm build` passing.\n- [x] ✅ **RSI-27: public trust per-page thresholds, OpenAPI docs example, and retention badge** (Medium-severity remediation) is complete (proven 2026-06-09):\n  - Public trust smoke now applies stricter `/datasets` pixel drift policy (`0.005`) than Contact/Privacy/Terms legal pages (`0.02`).\n  - `/api/docs` now renders the `/api/public-trust/summary` response example from `/api/openapi`.\n  - Public trust CI summary now includes a retention badge snapshot-locked by `tests/fixtures/public-trust-summary/summary-snapshot.md`.\n  - Proof packet: `tests/services/public-trust-smoke-artifacts.test.ts`, `tests/scripts/public-trust-smoke-script.test.ts`, `tests/services/public-trust-smoke-ci-summary.test.ts`, `tests/fixtures/public-trust-summary/summary-snapshot.md`, `tests/api/docs.test.ts`, `tests/api/openapi.test.ts`, focused RSI-27 output passing 13/9, `pnpm smoke:public-trust` passing with per-page thresholds, `unchanged=4`, and `pixel failures=0`, `pnpm test` passing 835/263, `pnpm lint` passing with one existing warning, and `pnpm build` passing.\n- [x] ✅ **RSI-28: JSON public trust threshold policy, agent-visible policy, and CI drift annotations** (Medium-severity remediation) is complete (proven 2026-06-09):\n  - Public trust smoke policy is now persisted in `config/public-trust-smoke-policy.json` and consumed by `scripts/smoke-public-trust-pages.ts`.\n  - `/api/public-trust/summary` now exposes the applied threshold policy for agents alongside latest smoke artifacts.\n  - CI summary tooling now emits warning annotations when screenshots change but remain under their configured threshold.\n  - Proof packet: `config/public-trust-smoke-policy.json`, `src/services/public-trust-smoke-policy.ts`, `scripts/smoke-public-trust-pages.ts`, `src/services/public-trust-summary.ts`, `src/contracts/zod/public-trust-summary.ts`, `src/services/public-trust-smoke-ci-summary.ts`, `tests/services/public-trust-smoke-policy.test.ts`, `tests/scripts/public-trust-smoke-script.test.ts`, `tests/api/public-trust-summary.test.ts`, `tests/services/public-trust-smoke-ci-summary.test.ts`, `tests/scripts/public-trust-ci-workflow.test.ts`, focused RSI-28 output passing 20/12, `pnpm smoke:public-trust` passing with JSON policy thresholds, `unchanged=4`, and `pixel failures=0`, `pnpm test` passing 838/264, `pnpm lint` passing with one existing warning, and `pnpm build` passing.\n- [x] ✅ **RSI-29: public trust reviewer rationale, schema rejection, and severity-grouped PR summaries** (Medium-severity remediation) is complete (proven 2026-06-09):\n  - Public trust policy pages now carry `reviewSeverity`, `reviewerNote`, and `reasonCodes`.\n  - `/api/public-trust/summary` now exposes reviewer rationale metadata in the applied threshold policy for agents.\n  - Public trust CI summaries and warning annotations now group under-threshold visual drift by high/medium/low route severity.\n  - Proof packet: `config/public-trust-smoke-policy.json`, `src/services/public-trust-smoke-policy.ts`, `src/services/public-trust-summary.ts`, `src/contracts/zod/public-trust-summary.ts`, `scripts/smoke-public-trust-pages.ts`, `src/services/public-trust-smoke-ci-summary.ts`, `tests/services/public-trust-smoke-policy.test.ts`, `tests/api/public-trust-summary.test.ts`, `tests/services/public-trust-smoke-ci-summary.test.ts`, `tests/fixtures/public-trust-summary/summary-snapshot.md`, focused RSI-29 output passing 18/11 plus CI-summary focused retest 2/1, `pnpm exec start-server-and-test \"pnpm dev\" http://localhost:3000 \"pnpm smoke:public-trust\"` passing with JSON policy metadata and `pixel failures=0`, `pnpm test` passing 839/264, `pnpm lint` passing with one existing warning, and `pnpm build` passing.\n- [x] ✅ **RSI-30: owner/reviewer initials, schema v2 fixture, and grouped annotation snapshot** (Medium-severity remediation) is complete (proven 2026-06-09):\n  - Public trust policy pages now carry `ownerInitials` and `reviewerInitials` alongside severity, notes, and reason codes.\n  - `/api/public-trust/summary` and CI drift summary rows now expose owner/reviewer initials for fast review routing.\n  - Planned `schemaVersion: 2` policy fixture and grouped warning annotation snapshot are now committed as executable contract evidence.\n  - Proof packet: `config/public-trust-smoke-policy.json`, `src/services/public-trust-smoke-policy.ts`, `src/services/public-trust-summary.ts`, `src/contracts/zod/public-trust-summary.ts`, `src/services/public-trust-smoke-ci-summary.ts`, `tests/fixtures/public-trust-policy/schema-v2-planned.json`, `tests/fixtures/public-trust-summary/grouped-annotations-snapshot.txt`, `tests/services/public-trust-smoke-policy.test.ts`, `tests/api/public-trust-summary.test.ts`, `tests/services/public-trust-smoke-ci-summary.test.ts`, focused RSI-30 tests passing 15/10, `pnpm exec start-server-and-test \"pnpm dev\" http://localhost:3000 \"pnpm smoke:public-trust\"` passing with `unchanged=4` and `pixel failures=0`, isolated transient `tests/api/artworks/by-id.test.ts` retest passing, final `pnpm test` passing 839/264, `pnpm lint` passing with one existing warning, and `pnpm build` passing.\n- [x] ✅ **RSI-1: Provider/pipeline boundary drift hardening** (High-severity remediation) is closed and proven:\n  - boundary contract test passes with allowed shared imports only,\n  - full `pnpm test` + `pnpm lint` + `pnpm build` cycle passed in-cycle,\n  - close-out evidence synchronized in `CLAUDE.md`, `README.md`, and this roadmap.\n- [x] ✅ **RSI-2: UI journey automation scope** (Medium-severity remediation) is closed and proven:\n  - matrix automation now spans role/provider combinations (`pnpm smoke:explore:matrix`), and `/api/objects`, `/api/works`, `/api/agents`, `/api/places`, `/api/sets` route assertions verify positive + negative paths for imported records,\n  - smoke probe evidence and status updates are synchronized in `CLAUDE.md`, this roadmap, and `README.md`.\n- [x] ✅ **RSI-3: Single-file and process-complexity reduction** (Low-severity remediation) is complete (proven 2026-06-09):\n  - Owner map and top-complexity target inventory are now finalized in `docs/risk-register.md` (Action 1 complete).\n  - Action 2 is complete: `src/services/publish-queue-worker.ts` split into helper modules with existing tests preserved.\n  - Action 3 is complete: `src/services/issues.ts` split into focused modules under `src/services/issues/` with behavior preserved.\n  - Action 4 is complete: `src/services/outbox.ts` split into focused modules under `src/services/outbox/` with behavior preserved.\n  - Action 5 is complete: `src/services/reconciliation.ts` split into focused modules under `src/services/reconciliation/` with behavior preserved.\n  - Action 6 is complete: `src/services/wiki-publish.ts` split into focused modules under `src/services/wiki-publish/` with behavior preserved.\n  - Action 7 is complete: `src/services/monitoring-telemetry.ts` split into focused modules under `src/services/monitoring-telemetry/` with behavior preserved.\n  - Proof packet: `pnpm test`, `pnpm lint`, and `pnpm build` for the closeout cycle, plus synchronized updates in `CLAUDE.md`, `docs/roadmap.md`, and `README.md` with this evidence path.\n  - Action 8 is complete: `scripts/authority-cache-refresh.ts` split into focused modules under `scripts/authority-cache-refresh/` with behavior preserved.\n  - Proof packet: `pnpm test`, `pnpm lint`, and `pnpm build` with synchronized updates in `CLAUDE.md`, `docs/roadmap.md`, and `README.md`.\n  - Action 9 is complete: `src/services/ai-layer.ts` split into focused modules under `src/services/ai-layer/` with API preserved in the facade.\n  - Proof packet: `pnpm test`, `pnpm lint`, and `pnpm build` all passed, with close-out updates synchronized in `CLAUDE.md`, `README.md`, and `docs/risk-register.md`.\n- [x] ✅ **RSI-4: Chat grounding and citation enforcement** (Medium-severity remediation) is complete (proven 2026-06-09):\n  - `/api/ai/chat` now returns sentence-level grounded citations (`[entityId, propertyPath]`) and refuses output when citation coverage is incomplete.\n  - Evidence is implemented in `app/api/ai/chat/route.ts` and `src/services/ai-chat.ts`.\n  - Proof packet: `tests/api/ai-chat.test.ts`, `pnpm test` (full suite), `pnpm lint`, and `pnpm build`; close-out updates synchronized in `CLAUDE.md`, `README.md`, and `docs/risk-register.md`.\n- [x] ✅ Expand HAL `_links` discoverability coverage from representative routes to all public entity-role routes as they land (enforced through protocol + provider conformance suites and `hal-entity-discoverability-conformance` quality checks).\n- [x] ✅ Add search-relation conformance breadth tests across additional provider search endpoints (beyond representative NGA/RKD/facade checks) with pagination drift assertions.\n  - Evidence: [`tests/quality/hal-search-relations-conformance.test.ts`](/C:/Projects/metamuseum/tests/quality/hal-search-relations-conformance.test.ts) now validates relation and pagination behavior for Louvre, Harvard, Smithsonian, V&A, Princeton, Europeana, AIC, CMA, and Rijks routes in addition to existing representative checks.\n- [x] ✅ Keep execution-policy gates strict: no provider/validation merges without standards mapping + fixture anchors, and no protocol-affecting merges without conformance coverage.\n  - Evidence: [`tests/quality/execution-policy-gates.test.ts`](/C:/Projects/metamuseum/tests/quality/execution-policy-gates.test.ts), [`.github/pull_request_template.md`](/C:/Projects/metamuseum/.github/pull_request_template.md).\n\nSuggested branch name (used): `codex/era-c1-hal-search-conformance-breadth`.\n\n<!-- 2026-07-01T18:13:00Z fix: TS6 compat -->\n\n<!-- 2026-07-01T18:28:55Z style: homepage color refresh -->\n<!-- last-session: 2026-07-01T19:07:54Z -->\n","sections":[{"level":2,"heading":"Status (as of July 7, 2026)","anchor":"status-as-of-july-7-2026"},{"level":3,"heading":"Current Launch Readiness","anchor":"current-launch-readiness"},{"level":3,"heading":"Current SaaS Readiness","anchor":"current-saas-readiness"},{"level":3,"heading":"SaaS Commercialization Strategy","anchor":"saas-commercialization-strategy"},{"level":3,"heading":"SaaS Roadmap Track","anchor":"saas-roadmap-track"},{"level":3,"heading":"SaaS Product Backlog","anchor":"saas-product-backlog"},{"level":3,"heading":"Current Evidence Blockers","anchor":"current-evidence-blockers"},{"level":3,"heading":"Next Operating Plan","anchor":"next-operating-plan"},{"level":2,"heading":"Linked Art adherence uplift (current -> high)","anchor":"linked-art-adherence-uplift-current-high"},{"level":3,"heading":"A. Validation architecture depth (B2 follow-through)","anchor":"a-validation-architecture-depth-b2-follow-through"},{"level":3,"heading":"B. Provider rollout completeness (B5)","anchor":"b-provider-rollout-completeness-b5"},{"level":3,"heading":"C. HAL + Search relations conformance (rounds 71-79)","anchor":"c-hal-search-relations-conformance-rounds-71-79"},{"level":3,"heading":"D. Era B exit-gate closure readiness","anchor":"d-era-b-exit-gate-closure-readiness"},{"level":2,"heading":"Stack decisions — locked in","anchor":"stack-decisions-locked-in"},{"level":2,"heading":"Era delivery history","anchor":"era-delivery-history"},{"level":2,"heading":"Cross-cutting standards (apply from Slice 1 onward)","anchor":"cross-cutting-standards-apply-from-slice-1-onward"},{"level":2,"heading":"What this roadmap deliberately does NOT do (yet)","anchor":"what-this-roadmap-deliberately-does-not-do-yet"},{"level":2,"heading":"What I'd build next, concretely","anchor":"what-i-d-build-next-concretely"}],"html":"<h1 id=\"meta-museum-roadmap\">Meta Museum Roadmap</h1>\n<p>This is the current, authoritative roadmap. It supersedes development-roadmap.md(development-roadmap.md) (kept as legacy reference for the pre-Next.js prototype).</p>\n<p>The <strong>north star</strong> is linked-art/LinkedArtSOTAWebApp.md(linked-art/LinkedArtSOTAWebApp.md). Anywhere this document is silent, the SOTA spec wins for <em>architecture</em>; this document wins for <em>sequencing</em> — what gets built when, and what is deferred.</p>\n<p>For provider-expansion and validation slices, linked-art/LinkedArtModel1.0-Reference.md(linked-art/LinkedArtModel1.0-Reference.md) is a required standards input for implementation and AIDD + TDD.</p>\n<p>That reference is now the round-based standards ledger for model/API/schema/search/protocol conformance, and roadmap execution assumes tests are mapped to its fixture anchors.</p>\n<p>---</p>\n<h2 id=\"status-as-of-july-7-2026\">Status (as of July 7, 2026)</h2>\n<p>&lt;!-- BEGIN:PROJECT_STATS --&gt;</p>\n<p>&lt;!-- Generated by `pnpm docs:stats`; do not edit by hand. --&gt;</p>\n<p>| Generated project stats | Current value |</p>\n<p>|---|---|</p>\n<p>| Next.js | `16.2.9` |</p>\n<p>| React | `19.2.4` |</p>\n<p>| App page files | root homepage + `33` non-root page files (`34` total) |</p>\n<p>| API route handlers | `146` `app/api` route handlers |</p>\n<p>&lt;!-- END:PROJECT_STATS --&gt;</p>\n<p>  Review-goal deployment evidence now distinguishes deployed Render service probes from documented local fallback mode: `pnpm review:goals` only counts the validation/reconciliation service goal when both selected checks show passing public HTTPS Render `/health` probes, rejects HTTP, non-health, placeholder, local, or private-network probe text, and launch readiness also selects those same deployed service checks. Launch readiness additionally selects worker scheduler readiness, Auth.js secret, GitHub OAuth credential, live signin/session route, production public-base URL, social-preview base URL, database authentication, deployment activation freshness, and public-read uptime source checks from deployment preflight, plus crawler-preview checks from both launch evidence and launch review, so missing cron/secret wiring, localhost, non-HTTPS, protected, mismatched share URLs, missing auth credentials, stale database credentials, stale active Vercel deployments, missing uptime-source setup, or missing Render service probes stay explicit deployment blockers before Open Graph/Twitter/canonical, preview-image, public-read, a11y, and probe-based uptime evidence can be trusted; the `launchEvidenceReady` coarse flag now requires those selected launch-evidence, launch-review, and deployment-preflight rows before it can pass. The long-term goal now also selects the Era C exit-gate `sota204P95`, `publicReadUptime`, `activityFeedAdoption`, and `sota26Kpis` rows, so measured p95 misses, insufficient uptime depth, missing external consumers, and KPI export gaps are real-world blockers with `pnpm era-c:exit-gate:public` remediation rather than a single opaque exit-gate failure; its coarse readiness flag requires both the selected runway rows and Era C rows before counting 30-day evidence ready. Manual public evidence refreshes should use `pnpm monitoring:telemetry:public`, `pnpm era-c:exit-gate:public`, or `pnpm longterm:evidence:public`, which force probe-backed uptime against `https://www.metamuseum.org` and avoid inheriting localhost from `.env.local`. The ActivityStreams coarse readiness flag now requires both selected rows, `activity.declaredConsumers` and `activity.durableSubscriptions`, before counting syndication ready, so a top-level ready artifact cannot hide missing or unverified durable subscriptions. The version-45 audit also scopes production launch-packet a11y failures to the deployment-environment lane instead of treating them as local-refresh debt, and includes `analytics-consent-posture` as a local governance goal backed by `pnpm privacy:consent:check` and `artifacts/privacy/analytics-consent-latest.json`. Coarse external blocker rows and selected artifact-check rows now include their own next-evidence text, remediation commands, and artifact targets for launch, Render probes, 30-day SLO/uptime, Era C exit-gate, ActivityStreams syndication, paid-pilot evidence, and consent-posture checks, with a command-and-scope `nextActions` list that unions every artifact path into machine-readable `artifactTargets`, preserves each blocker as a goal-scoped action `blockerIds` reference whose length matches `blockerCount`, preserves every distinct evidence requirement as `nextEvidenceRequirements`, keeps local/deploy/real-world queueing as `executionScope`, exposes top-level lane counts as `nextActionSummary.actionCount`, includes blocker-lane `externalEvidenceBlockerSummary.nextActionIds`, `actionCount`, `nextEvidenceRequirements`, and `requirementCount`, includes per-goal `blockedByExternalEvidenceGoals.nextEvidenceRequirements`, `requirementCount`, `actionCount`, `commandCount`, `artifactCount`, and `scopeCount`, reports the local-only CI result as top-level `localGateStatus`, reports the final strict gate as top-level `strictGateStatus`, lists the strict-gate blocker lanes in `strictGateFailureReasons`, adds structured strict-gate rows in `strictGateFailureSummary`, adds consolidated strict-gate commands/artifacts/goals in `strictGateHandoff`, includes exact blocker IDs in `strictGateHandoff.blockerIds` and `strictGateHandoff.scopeBreakdown[].blockerIds`, includes exact action IDs in `strictGateHandoff.nextActionIds` and `strictGateHandoff.scopeBreakdown[].nextActionIds`, includes explicit strict next-action totals in `strictGateHandoff.nextActionCount` and `strictGateHandoff.scopeBreakdown[].nextActionCount`, includes explicit affected-goal totals in `strictGateHandoff.goalCount` and `strictGateHandoff.scopeBreakdown[].goalCount`, includes distinct remediation-command totals in `strictGateHandoff.commandCount` and `strictGateHandoff.scopeBreakdown[].commandCount`, includes distinct evidence-artifact target totals in `strictGateHandoff.artifactCount` and `strictGateHandoff.scopeBreakdown[].artifactCount`, includes distinct next-evidence requirement totals in `strictGateHandoff.requirementCount` and `strictGateHandoff.scopeBreakdown[].requirementCount`, includes consolidated strict-gate next-evidence sentences in `strictGateHandoff.nextEvidenceRequirements`, splits those strict handoffs by scope in `strictGateHandoff.scopeBreakdown`, and exposes both `score.blockedByExternalEvidence` and `blockedByExternalEvidenceGoals` so local-gate-complete goals do not hide the true external-blocked total or the named goal handoffs. Each blocked-goal row now carries exact blocker IDs, action IDs, action-level blocker/artifact/requirement counts, action counts, scopes, scope counts, remediation commands, command counts, artifact targets, artifact counts, distinct top-level evidence requirements and counts, an `actionBreakdown` mapping each command to the blockers it remediates with goal-local evidence requirements, and a `scopeBreakdown` that splits that goal&#39;s action, next-action ID, blocker, command, artifact, and requirement arrays and totals across local-refresh, deployment-environment, and real-world-evidence lanes; the schema now requires those blocked-goal handoff arrays to be populated and duplicate-free before the artifact contract is considered valid. The latest local audit reports `complete=7/12`, with launch readiness, Render service probes, managed pilot, 30-day SLO/uptime, and ActivityStreams syndication named in `blockedByExternalEvidenceGoals`. The local-refresh lane has `0` blockers, deployment-environment has `4` blockers driven by launch-evidence, launch-review, Era C proof, and Render service probes, and the real-world lane still has `19` blockers for long-window, ActivityStreams `Delete` type coverage, KPI, and pilot proof. `pnpm review:goals:local` now lets CI fail only on missing local commands/docs/tests while `pnpm review:goals:check` stays reserved for the final real-evidence 10/10 gate; documentation drift tests scan public docs for stale demo-script-only, launch-preflight-green, strict-handoff count drift, and broad-public-SaaS readiness claims that bypass that strict gate, and the Era C evidence workflow enforces the local gate before uploading the review-goals packet.</p>\n<ul><li>[ ] ⚠️ <strong>Strict 10/10 readiness is not green yet</strong>: `pnpm review:goals:check` still reports `status: external-evidence-required`, `local gate status: passed`, and `strict 10/10 gate status: failed`, but stale deployment proof is no longer the story. GitHub CI is green, and the July 4 production preflight passes `20/20` when the non-secret rotation timestamp and rotated-key list are supplied: Postgres storage, `sslmode=verify-full`, live Neon authentication, active Vercel deployment freshness after secret rotation, auth routes, public-read reachability, validation/reconciliation Render `/health` probes, IIIF tile reachability, DR drill freshness, no production smoke override token, `security.secretRotation`, and `security.secretHistory` all pass. Live probes against `https://www.metamuseum.org` return `200` for `/api/health`, `/api/records`, and `/api/auth/signin`, while `/agents` redirects public users to sign-in. The refreshed production launch-evidence packet passes `8/9`, launch review passes `7/8`, and the remaining launch-review failure is the Era C real-world evidence row. The latest review-goals handoff reports `4` deployment-environment blockers plus `19` real-world-evidence blockers for deployed Render service probes, clean 30-day SLO/uptime windows, ActivityStreams `Delete` type coverage after `3/3` real external consumers and restored `3/3` durable callback rows, partner-confirmed `Update`, paid-pilot entitlement/activation/support-load/KPI proof, retention, and gross-margin evidence; Te Papa first outreach is now recorded, but no reply or paid-pilot proof exists yet. The refreshed 10/10 tracker is `docs/roadmap-to-10.md`(roadmap-to-10.md).</li><li>[ ] ⚠️ <strong>Strict real-world lane:</strong> the real-world lane still has `19` blockers, and the highest-leverage remaining ActivityStreams unblocker is real `Delete` evidence. The first reviewed metadata `Update` row is live in production from a real Met object `437133` metadata delta, and MetaHistoryBook re-read it as `metahistorybook-harvester-prod` at `2026-07-05T19:50:30Z` with `totalItems: 1`, real non-synthetic `source.kind: reviewed-update`, conformant projections, and the shared `Q432253` reconciliation. `pnpm providers:coverage:seed` now brings the provider tombstone-watch corpus to all `14/14` source-provider lanes by seeding Harvard from a public object page and Europeana from its read-only Record API status surface, with `0` skipped and `0` failed rows. MoMA is tracked separately as an open-data snapshot provider: `pnpm moma:dataset:diff` compares explicit Artworks snapshots and writes review-required removal candidates without creating ActivityStreams `Delete` readiness. The `Delete` side remains intentionally blocked because the latest provider-aware `pnpm activity:tombstone:scan` run considered `126` stored records at `2026-07-10T01:07:06.186Z`, scanned `68` unique upstream targets across all `14` source providers, skipped `5` unknown/local records, collapsed `53` duplicate Met targets, and found `0` real upstream `404`/`410` tombstones. Next strict step: send a separate `Delete` deploy-note only after a genuine tombstone appears. The same lane still needs the invoice-backed pilot, 30-day SLO/uptime, KPI, retention, and gross-margin proof.</li><li>[x] ✅ <strong>Latest local verification:</strong> ActivityStreams syndication evidence, provider tombstone-watch evidence, review-goals local gate, and focused review/readiness tests pass for this evidence refresh; the remaining strict blockers are real-world proof, not stale callback, dataset, or local-readiness artifacts. The 10/10 tracker has a drift guard against the latest `artifacts/review-goals/review-goals-latest.json` strict-handoff counts so stale blocker totals are caught in tests.</li><li>[x] ✅ <strong>B6.1 equivalent-URI reconciliation proof:</strong> exhibition/literature candidates now count Linked Art `equivalent[]` identity hints on works and embedded participants as identifier/participant overlap while preserving full opaque URI evidence. Compact Wikidata, OpenLibrary, and Getty keys are derived only from recognized authority URI/CURIE shapes, and `tests/quality/reconciliation-exhibitions-literature.test.ts` guards arbitrary URI paths from being promoted to authority identifiers.</li><li>[x] ✅ <strong>Durable callback proof guard:</strong> `pnpm activity:subscriptions:guard` now runs inside `pnpm activity:syndication:evidence`, verifies the three accepted partner callback rows plus their non-placeholder callback proof artifacts, preserves the current zero rejected subscriptions state, and is called explicitly by the nightly Era C evidence workflow. The durable consumer/subscription ledgers and callback proof JSONs are intentionally trackable while the rest of the generated ActivityStreams artifact directory stays ignored.</li><li>[x] ✅ <strong>Strict handoff public-doc drift guard:</strong> documentation drift tests now compare the latest review-goals strict handoff counts against the README, roadmap, and roadmap-to-10 summaries, so total production-proof blockers and deployment/real-world lane counts cannot quietly diverge after evidence refreshes.</li><li>[x] ✅ <strong>Deterministic local test gate:</strong> `pnpm test` and `pnpm test:coverage` now pass Node&#39;s test runner `--test-concurrency=1` after repeated full-suite runs exposed order-sensitive conformance files that passed in isolation and under the serial quality subset. This preserves the canonical green gate while the route-level conformance suites continue to exercise process-local env/fetch/storage behavior.</li><li>[x] ✅ <strong>Core stack and runtime</strong>: generated project stats above provide the current Next.js and React pins; TypeScript strict + custom CSS remain the runtime baseline. Latest pilot outreach reply/evidence guard passed focused evidence/outreach/activation/support operator/service/offer/page/storage/docs/exporter checks (`70` tests / `13` suites), final `pnpm test` (`1103` tests / `310` suites), `pnpm lint`, and `pnpm build`; `/pilot` now renders a typed zero-complete activation evidence ledger with the six canonical seven-day pilot milestones, while `src/services/pilot-outreach-events.ts`, `src/services/pilot-activation-events.ts`, `src/services/pilot-support-issues.ts`, and `src/services/pilot-evidence-packet.ts` record sequence-guarded exact-account outreach, ordered exact-tenant activation events, chronology/status/identity/severity/resolution-evidence-guarded support load, explicit blocked/ready pilot packet artifacts, blocker-first Markdown packet summaries, open-blocking-support readiness blockers, and overdue open support-response blockers, `pnpm pilot:outreach`, `pnpm pilot:activation`, `pnpm pilot:support`, and `pnpm pilot:evidence --markdown` let operators append, package, and share real dated evidence without hand-editing JSON, and the runbook forbids marking outreach, activation, support, or packet readiness complete from demo, fixture, smoke evidence, reply claims without prior sent evidence, replies dated before `sentAt`, sent follow-up dates that predate `sentAt`, tenant-mismatched activation evidence, later activation milestones without prior tenant evidence, support response deadlines before `openedAt`, support issue `requester`, `summary`, `openedAt`, or `severity` rewrites, resolved support issue `resolvedAt` or `resolutionSummary` rewrites, support resolutions before `openedAt`, or open support issues carrying resolution evidence. Tenant RBAC evidence still proves signed-in members cannot use sibling active-org cookies to read sibling record lists/details, write records into sibling/default storage, read/review/publish/write sibling wiki draft state, read/review/triage/write sibling annotation queues, read/write sibling AgentTask history, or steer scoped AI/editorial record-read outputs away from their authenticated org; proving signed-in non-members cannot use a cookie-selected org to read or mutate records, annotation, wiki draft, or scoped AI/editorial record-read outputs; and proving signed-in non-admin roles cannot use org administration or support-adjacent routes to list orgs, add memberships, create/revoke invites, or export org audit packets. Gated pilot API routes return stable `429`/`Retry-After` denials before parsing or work execution without changing monthly quota denial semantics. The membership-validated `metamuseum.activeOrgId` cookie drives shared preview, request-storage, and pilot route-gate scope without weakening test override or explicit `?tenantId=...` compatibility precedence. The workspace shell renders sanitized active-org status, org id, accessible-org count, storage scope, membership role, selector, stale-selection warning, and an `/orgs` switch/manage affordance without exposing invite token material. Workspace records, explore, entities, entity detail, artwork detail, graph, and patterns pages derive preview storage from authenticated org session scope when no compatibility `?tenantId=...` is supplied, while explicit tenant preview links still win for controlled pilot URLs. Manual pilot entitlements can bind to authenticated org ids while route usage gates prefer the selected active org for entitlement lookup and post-success counter writes before compatibility tenant headers. `/orgs` can render the operator console while admin-only org routes create/list orgs, memberships, sanitized invites, invite revocation, invite acceptance, form posts, org-scoped audit rows, and org audit export packets while Auth.js org scope continues to resolve from managed org memberships/invites before compatibility env mappings or pilot tenant headers. Wiki draft create/list/detail/review/publish access, live-publish sync-map artifacts, reverse-ETL state, and tenant preview pages remain scoped while unscoped public requests cannot see scoped tenant records or artifacts. Provider facade/direct provider/explorer/Linked Art import writes, public browse reads, records, jobs, AgentTask, annotation, audit, activity route storage, wiki draft storage/access routes, wiki sync-map routes, and tenant-scoped export/DR managed documents remain isolated. The temporary `metagenauto/` AG2 reference repo has been distilled into `docs/agents/ag2-extraction-notes.md` before removal from the app tree.</li><li>[x] ✅ <strong>Product surface</strong>: generated project stats above provide the current page and API handler counts; the live surface includes 14 provider integrations, ARK resolver, provider facade/readiness/capabilities, standards APIs, ActivityStreams, OpenAPI/docs, worker status API, AI query/chat/evals, org admin/invite APIs, org audit export, `/api/orgs/active` active-org selection, the `/orgs` operator console for org provisioning, memberships, invites, and revocation, `/workers` operator health for projection/publish drain lag, next cron wakeup, effective drain time, and disabled modes, workspace-shell active-org status with selector, stale-selection warning, and switch/manage affordance, persisted AgentTask review history, wiki publish/sync, annotations, public trust, IIIF routes, a larger rotating midnight/navy rain-blue home hero with bright lemon-yellow Meta Museum highlights, top-padded full-color unfiltered contained artwork, a verified Met/CMA/AIC clean-deploy fallback when local image-backed imports are absent, a centered non-overlapping navy artwork info panel, a white hero label, three source-backed real-artwork pathway cards with provider/maker/date/rights/link metadata instead of AI placeholder images, a more readable artwork detail facts panel with metadata-forward desktop proportions and full-width long source fields, a HAL-powered “Related” panel on entity and artwork detail pages for followable Linked Art relation searches, a full-width “Live source network” homepage band that frames the current project as a source-backed workbench with numbered source metrics, provenance, rights/attribution context, citation checks, and editor-gated review signals, a `/projects` product case-study surface with a short “what matters in 90 seconds” evaluator brief, hidden technical proof disclosures, walkthrough video, proof strip, live route links, architecture evidence links, and an honest strict-readiness note, and the `/pilot` Managed Linked Art Launch Pilot offer page with shared primary/footer navigation access, named outreach status ledger, zero-complete activation evidence ledger, and validated operator flows for outreach and activation evidence.</li><li>[x] ✅ <strong>External evidence ledger</strong>: `/evidence` and `/api/evidence/ledger` now give evaluators a compact public proof surface over partner-confirmed `Update`, durable callback proof, MetaHistoryBook&#39;s FAIR/LOUD dataset reuse confirmation, the provider tombstone watch, 30-day SLO/uptime progress, and invoice-backed pilot blockers. `/api/evidence` is a compatibility alias and `/en/evidence` is an explicit locale route for external readers following locale redirects. It deliberately renders `Delete` as pending genuine upstream `404`/`410` evidence rather than treating an empty `type=Delete` feed as a defect to paper over, the production API falls back to public docs when generated artifact JSON is not bundled, and production responses include live probes for the current `Update` feed, Update `linkedArt.id` dereference into `/api/events/...`, intentionally empty `Delete` feed, dataset profile headers, and NDJSON export integrity. The ledger also publishes a tombstone-watch history from retained scan-run artifacts so repeated 14-provider scans are visible over time, not just the latest no-tombstone snapshot. `pnpm evidence:ledger:probe:check` now retains the live ledger result as `artifacts/evidence-ledger/evidence-ledger-probe-latest.json` plus timestamped run artifacts, the nightly Era C workflow captures/uploads those artifacts, and `/readiness` surfaces the latest probe as an operator source.</li><li>[x] ✅ <strong>Museums Victoria provider slice (2026-07-04)</strong>: added an item-first Museums Victoria Collections API provider with bounded `recordtype=item` search, object fetch, import, `/explore` source toggle, provider facade routes, media-rights preservation, First Peoples/cultural-context review notes, rights-map coverage, and generated pass/fail fixtures. Articles, species, and specimens remain intentionally excluded until separate semantic mapping exists. Provider notes: docs/providers/museumsvictoria-collections-api.md(providers/museumsvictoria-collections-api.md).</li><li>[x] ✅ <strong>Portfolio product polish controls</strong>: `src/services/portfolio-product-polish-controls.ts`(../src/services/portfolio-product-polish-controls.ts) and `tests/services/portfolio-product-polish-controls.test.ts`(../tests/services/portfolio-product-polish-controls.test.ts) now keep the `/projects` case study, product walkthrough video, standalone overview HTML, public docs freshness metadata, shared navigation, and strict-readiness copy boundary in one executable report.</li><li>[x] ✅ <strong>Operator readiness page</strong>: `/readiness` now condenses existing ignored readiness artifacts into one editor-gated status view with local-vs-strict claim boundaries, source freshness, blocker rows, and next remediation commands. It also renders the generated acceptance ledger from long-window maintenance, ActivityStreams community-outreach, ActivityStreams partner-pack, paid-pilot buyer-pack, FAIR/LOUD dataset reuse, evidence-ledger live probes, and SOTA KPI artifacts, plus a dataset reuse source card for MetaHistoryBook&#39;s external confirmation of dataset discovery, checksum integrity, export pagination, object-level `equivalent[]`, Wikidata reconciliation, and license-scope clarity. The strict readiness audit source card now shows the `strictGateHandoff` blocker, next-action, command, artifact, and requirement counts, while the page also exposes the `review-goals.nextActions[]` strict handoff as an action queue grouped by execution scope with deployment-environment and real-world proof lane totals before row-level commands, so local gates, optional evidence rows, outreach context, repair hints, executable strict actions, and strict production proof remain visibly distinct.</li><li>[x] ✅ <strong>Operator stale-preflight guard</strong>: `/readiness` now fails production deployment-preflight source rows when the latest artifact is missing current selected secret evidence checks (`security.secretRotation`, `security.secretHistory`), even if the stale artifact summary says `pass`, and adds `pnpm launch:preflight:production` to the next-command list.</li><li>[x] ✅ <strong>Readiness mismatch guard</strong>: `/readiness` preserves local-gate and strict-gate proof booleans from review-goals artifacts, renders strict production proof as “not proven” whenever external evidence is still required, and downgrades any global strict-gate pass when the five real-world evidence contracts are not independently satisfied.</li><li>[x] ✅ <strong>Strict evidence loop visibility</strong>: `/readiness` now surfaces the review-goals handoff as three distinct evidence lanes — local refresh, deployment-environment proof, and real-world production proof — with blocker counts, commands, requirements, and artifact targets kept separate so local gate confidence cannot be presented as strict readiness. It also renders five strict external evidence contracts for 30-day SLO/uptime, ActivityStreams adoption, invoice-backed paid pilot, pilot retention, and gross-margin proof; each contract rejects local substitutes, names the source and acceptance-ledger rows it depends on, and remains failed until its own real-world evidence lands. Production launch-packet a11y remediation now points operators at `BASE_URL=https://&lt;deploy-host&gt; pnpm a11y:check` in the deployment-environment lane, so a stale embedded artifact command cannot look like a local-only fix.</li><li>[x] ✅ <strong>Evidence script ownership</strong>: high-churn launch, review-goals, long-term, ActivityStreams, pilot, continuity, AI-eval, worker, and governance commands now have a typed owner registry plus a regression guard, with the human handoff at `docs/ops/evidence-script-ownership.md`(ops/evidence-script-ownership.md). The ActivityStreams owner row explicitly covers `pnpm activity:subscriptions:guard` so durable callback verification cannot drift outside the accountable evidence lane. Package-script namespaces now also have owner, preferred-entry-point, and pruning-rule controls so new `namespace:*` command groups cannot appear unclassified.</li><li>[x] ✅ <strong>Operations risk controls</strong>: `src/services/operations-risk-controls.ts`(../src/services/operations-risk-controls.ts) and `tests/services/operations-risk-controls.test.ts`(../tests/services/operations-risk-controls.test.ts) now summarize and regression-check the four recurring operations risks: the large API route surface with first-level route-family owner/review-lane classification, package-script namespace classification plus high-churn script ownership, mixed Vercel/Neon/Render/Redis/Solr/GraphDB topology, and schema/freshness/retention controls for readiness artifacts.</li><li>[x] ✅ <strong>Turbopack runtime-file warning cleanup</strong>: runtime-only artifact, storage, SHACL, schedule, and queue file reads now use `src/utils/runtime-fs.ts`(../src/utils/runtime-fs.ts), so `pnpm build` keeps those dynamic paths out of static file tracing and finishes without broad file-pattern warnings.</li><li>[x] ✅ <strong>Public docs metadata freshness</strong>: `/api/docs/manifest` now reports response `generatedAt` separately from declared source `sourceUpdatedAt` plus `sourceUpdatedDoc` latest-source checksum metadata, keeping Vercel bundle mtimes or response timing from being mistaken for source-document currency.</li><li>[x] ✅ <strong>OKF / LLM wiki seed</strong>: docs/knowledge(knowledge/index.md) now starts a project-local Open Knowledge Format-style bundle with a root index, append-only log, source summaries for the OKF announcement and LLM Wiki pattern note, concept pages for OKF, the LLM Wiki pattern, and the Meta Museum knowledge system, plus a maintainer schema that tells agents how to ingest, query, and lint the wiki. `pnpm okf:check` validates that reserved `index.md`/`log.md` files stay separate from typed concept documents with non-empty `type` frontmatter.</li><li>[x] ✅ <strong>Linked Art HAL reference capture</strong>: linked-art/api/hal.md(linked-art/api/hal.md) now records the `_links` boundary, CURIE/version/alternate/collection rules, the detailed high-priority relation-search notes captured so far, and the complete 95-name upstream relation inventory extracted from the cloned `linked.art/scripts/hal_links.tsv` mirror. The doc keeps the current implementation boundary explicit: semantic activity/concept/object-part/object-to-work/production-influence/group-formation/custody/encounter/ownership/production/set-creation/work-aboutness/representation/work-creation/work-publication/place-activity/active-place data is preserved; entity-role responses now expose followable usage-indexed named HAL relation links for `la:objectProducedByAgent`, `la:objectOwnedByAgent`, `la:objectCuratedByAgent`, `la:objectMemberOfSet`, `la:objectPartOfObject`, `la:objectCarriesWork`, `la:objectShowsWork`, `la:workAboutAgent`, `la:workRepresentsAgent`, `la:workAboutOrRepresentsAgent`, `la:activityCarriedOutByAgent`, `la:activityUsedObject`, `la:activityTookPlaceAtPlace`, `la:groupFoundedByAgent`, `la:objectEncounteredByAgent`, `la:agentActiveAtPlace`, `la:objectProductionInfluencedByAgent`, `la:objectProductionInfluencedByObject`, `la:objectProductionInfluencedByPlace`, `la:objectProductionInfluencedByWork`, `la:setCreatedByAgent`, `la:conceptInfluencedByObject`, `la:workCreatedByAgent`, and `la:workPublishedByAgent`; `/api/relations` now exposes the supported relation definition catalog with domain/range/search-template metadata; and `/api/relations/{relation}` pages carry relation/current/return-class/conformance/partOf metadata rather than a bare result list. Full relation breadth for work/object/set/place/concept variants beyond the currently indexed subset and other upstream relation families remains next implementation work with failing-first relation tests. The Linked Art inspector also warns when dereferenceable embedded activity/shared-structure IDs omit `_complete: false`.</li><li>[x] ✅ <strong>HAL relation explorer UI</strong>: entity and artwork detail pages now reuse those followable `la:*` relation links in a visible “Related” panel, exposing produced-object, work-aboutness/representation, owner/curator, object-part, and place-activity searches as clickable `OrderedCollectionPage` API affordances instead of keeping relation-search value hidden in JSON only.</li><li>[x] ✅ <strong>Linked Art relation-search expansion slices</strong>: `activityCarriedOutByAgent`, `activityUsedObject`, `activityTookPlaceAtPlace`, `groupFoundedByAgent`, `objectEncounteredByAgent`, `agentActiveAtPlace`, `objectCarriesWork`, `objectShowsWork`, `objectProductionInfluencedByAgent`, `objectProductionInfluencedByObject`, `objectProductionInfluencedByPlace`, `objectProductionInfluencedByWork`, `setCreatedByAgent`, `conceptInfluencedByObject`, `workAboutOrRepresentsAgent`, `workCreatedByAgent`, and `workPublishedByAgent` now have registry metadata, sparse POST preservation where needed, entity-index extraction for top-level and embedded activities, formation actors, encounter actors, agent active-place references, physical object `carries`/`shows` object-to-work evidence, production influences, set creation, concept influence, and work aboutness/representation/creation/publication evidence, `/api/relations` discovery, followable entity `_links`, and `OrderedCollectionPage` tests proving Activity/Event, Group, HumanMadeObject, Agent, Place, Set, Type, and Work return-class behavior.</li><li>[x] ✅ <strong>Linked Art provenance search surface</strong>: `/api/provenance` now provides a provenance-specialized Linked Art Search API page over stored provenance wrappers, with `kind=acquisition`, `kind=custody`, `kind=transfer`, `kind=move`, and `kind=right-acquisition` filters plus optional `object=` filtering. Responses include `provenanceKind`, `conforms_to`, `partOf`, `la:provenanceProfile`, source object summaries, wrapper activities, and matching `part[]` entries so acquisition, custody, indeterminate transfer, movement, and rights-acquisition evidence stays distinct at discovery time. Evidence: `tests/api/provenance.test.ts`(../tests/api/provenance.test.ts).</li><li>[x] ✅ <strong>HAL entity envelope upgrade</strong>: shared entity/record HAL responses now emit `self`, a templated Linked Art `la` CURIE, `la:activityFeed`, and link-object `la:apiVersion`/`la:modelVersion` entries with `href` and `name`, replacing the older string-only version metadata while keeping HAL out of the semantic graph payload.</li><li>[x] ✅ <strong>FAIR/LOUD dataset publication surface</strong>: `/api/datasets` now publishes a machine-readable DCAT/DataCite/VoID-style JSON-LD dataset profile with dataset id, version, checksum, license, update cadence, distributions, and canonical identifier policy. `/api/datasets/exports/records?format=jsonld|ndjson` provides downloadable versioned record envelopes with per-record rights/provenance packaging and object-level `equivalent[]` links projected from stored equivalents, provider URLs, public object pages, and Wikidata entity URLs; `/api/providers/capabilities` advertises those dataset distributions for follow-your-nose discovery; dataset responses expose id/version/distribution/checksum/license headers for integrity checks without body parsing; `/api/datasets` states that CC BY 4.0 governs export packaging/metadata while per-record rights govern object/content/media reuse; `/datasets` links the machine-readable profile and exports; and linked-art/canonical-identifier-policy.md(linked-art/canonical-identifier-policy.md) documents persistence, redirects, content negotiation, ARK/DOI strategy, reconciliation equivalents, and license scope. MetaHistoryBook re-read dataset version `2026.07.06+sha256.43eb7f0049c9` and confirmed `53/54` non-empty `record.equivalent[]` rows, `47/54` Wikidata rows, checksum validity, pagination/discovery, and license-scope clarity, converting the dataset reuse package from self-verified to partner-verified evidence. This improves reuse packaging without treating the remaining real-world Delete or 30-day SLO/uptime evidence as complete.</li><li>[x] ✅ <strong>Performance scale controls</strong>: `src/services/performance-scalability-controls.ts`(../src/services/performance-scalability-controls.ts) and `tests/services/performance-scalability-controls.test.ts`(../tests/services/performance-scalability-controls.test.ts) now exercise cold-record SLO miss/depth behavior, Solr/GraphDB projection enablement thresholds, bounded cron backlog escalation, and provider cache/rate-limit/validation-drift safeguards.</li><li>[x] ✅ <strong>Calendar-auditable long-window evidence</strong>: `pnpm longterm:evidence` and `pnpm longterm:evidence:maintenance` now include observed and missing UTC days for SLO and public-read uptime windows, and the maintenance Markdown names missing days so 30-day readiness cannot be inferred from clustered or opaque sample totals. The maintenance report also carries SLO trend-intake diagnostics, grouped repair-queue rows for retained SLO metric failures and public-read uptime path failures, row-level and per-failed-sample age-out dates, acceptance rows for SLO sample depth, SLO failure-free status, uptime observation depth, uptime availability, ActivityStreams consumer depth, activity-type coverage, and strict long-term packet refresh; `/readiness` shows the repair-queue count without treating it as proof. The latest July 6 long-window maintenance artifact has `20/30` retained deployed SLO samples across `7/30` observed UTC days, `13/30` passing SLO samples across `6/30` passing days, `7` failed/incomplete retained SLO rows, and SLO trend intake of `23` raw timestamped rows with `20` inside the report window and `3` older than the window. Public-read uptime has `117` retained probe snapshots with `0.9744` availability across `9/30` observed days, and the last retained failed SLO/uptime sample ages out by `2026-07-28T20:28:03.851Z`; daily passing-depth evidence is ready no earlier than `2026-07-29T09:15:00.000Z` if every future sample passes and adoption evidence lands. Review-goals now derives long-term blocker detail from retained sample counts, failed/incomplete sample counts, distinct-day coverage, uptime availability, and missing ActivityStreams activity types, so the strict handoff cannot hide behind aggregate sample totals.</li><li>[x] ✅ <strong>Scheduled public-read probe contract</strong>: `.github/workflows/era-c-exit-gate-evidence.yml` now defaults `METAMUSEUM_PUBLIC_READ_BASE_URL` to `https://www.metamuseum.org` and runs `pnpm era-c:exit-gate:public`, so nightly Era C packets require production probe-backed uptime instead of inheriting local or variable-only telemetry.</li><li>[x] ✅ <strong>CI readiness workflow repair</strong>: GitHub build/smoke jobs now set a CI-only dummy `AUTH_SECRET` so the production auth-secret throw remains intact while clean runners can compile and start Next, env-loader tests isolate inherited CI secrets before checking local file assignment, the standalone public-trust smoke filter watches auth/workflow changes, review-goals tests assert evidence-loop invariants from generated reports and tolerate both local-present and clean-runner-missing artifact blocker shapes, ActivityStreams adoption controls keep ignored generated partner-pack outputs as handoff targets without requiring them to exist in a clean checkout, the a11y smoke treats expected `/agents` and `/automation` Auth.js redirects as protected-route passes, and the Era C evidence workflow force-adds only its explicit rolling-evidence allowlist.</li><li>[x] ✅ <strong>SOTA §26 KPI export path</strong>: `pnpm monitoring:kpi-evidence` writes current-environment `monitoring/kpi-evidence.json` from record-enrichment and reconciliation decision counts, `pnpm monitoring:kpi-evidence:production` now loads repo env files before requiring Postgres storage and production source labels, real reviewed/accepted auto-link counts must be supplied together, and reviewed precision now also requires `--reviewed-precision-source` naming production review evidence before it enters the KPI snapshot. The KPI enrichment counter now counts unique recognized authority references rather than authority source families; the July 4 local export writes `1/5` ready acceptance rows, `0/4` ready production capture rows, `2` KPI metric blockers, and `diagnostics.handoffSummary.status: needs-production-evidence`; the record denominator is present, local enrichment is `52/57` (`0.9123`) against the `46/57` threshold, reconciliation candidates remain `0`, and reviewed precision still needs real reviewed/accepted auto-link counts plus a production review source. The handoff now separates strict source-shape work from metric work: `nextCommand` asks for the production KPI export, while `nextMetricCommand` points directly at production reconciliation distribution capture with `--auto-link`, `--weekly-digest`, `--human-review`, and `--drop-candidate`; `/readiness` shows both the metric-specific command and the required metric evidence text in the SOTA KPI source card. The export includes acceptance rows for production record export, enrichment denominator, production reconciliation export, reviewed precision counts/source, and strict Era C refresh readiness, plus KPI diagnostics with metric previews, `diagnostics.evidenceNeeds`, a capped `sampleRecordGaps[]` enrichment repair sample for under-authoritied record IDs, each sample&#39;s existing recognized authority URIs and suggested Linked Art fields, production-only `diagnostics.capturePlan` rows, and `diagnostics.handoffSummary` so the source-shape and metric next evidence are visible without inferring them from the failed gate.</li><li>[x] ✅ <strong>ActivityStreams onboarding ledger</strong>: `pnpm activity:partner-pack` now gives each requested consumer copy-ready outreach text, a partner response template, an evidence checklist, and structured acceptance rows for declared-feed-read, activity-type coverage, durable-subscription, callback-verification, and strict-gate-refresh proof. The placeholder pack keeps `consumerIds: []` and `pending-consumer-id` rows, so outreach scaffolding cannot count as strict adoption evidence. `pnpm activity:syndication:evidence` emits `consumerOnboarding.rows` with feed-read, durable-subscription, callback-verification, blocker, next-action, and evidence-ref fields so real external adoption can be tracked consumer by consumer.</li><li>[x] ✅ <strong>Linked Art-native activity stream lift (2026-07-04, activity-class/provenance coverage lifted 2026-07-06)</strong>: `/api/activity` now embeds a `linkedArt` JSON-LD projection on every ActivityStreams item, extracts semantic record events from `produced_by`, `created_by`, `modified_by`, `destroyed_by`, `removed_by`, `encountered_by`, `formed_by`, `dissolved_by`, `born`, `died`, title/custody transfer, and `used_for` properties, emits conservative `record-backfill` `Create` activities for otherwise uncovered stored records, supports `type`, `source`, `provider`, `object`, `since`, `until`, and cursor sync filters, keeps offset `nextPage` compatibility, defaults absent `limit` to a 25-item page, falls back to offset `next` links instead of emitting invalid cursors, and exposes object-scoped feeds at `/api/activity/object/{encodedObjectId}`. Linked Art `Destruction` and `Dissolution` stay semantic `Update` feed rows, so the strict ActivityStreams `Delete` lane remains reserved for real upstream `404`/`410` tombstones; dereferenceable activity IDs preserve source-supplied `_complete: false`; `Set` records emit `Creation`/`created` rows instead of physical `Production` rows, while record detail keeps `member_of` links on member records instead of inventing inverse `member[]` lists on the Set; `Birth`/`Death` projections suppress disallowed `carried_out_by` and `used_specific_object` fields; and provenance wrapper activities preserve names, classifications, descriptions, relative `before`/`after` ordering, and bundled `part[]` entries such as `Encounter`, `Acquisition`, indeterminate `Transfer`, `RightAcquisition`, `Move`, and `Payment`, including find/rediscovery encounters, explicit rights establishment/invalidation, percentage ownership shares, copyright rights, unknown-transfer evidence without title/custody assertions, multiple-owner, agent-carried acquisition, exchange, custody-transfer loans, movement origin/destination places, theft/loss custody changes, commission/service payment details, auction event classifications, auction-of-lot identifiers, lot `Set` `used_specific_object` values, `part_of` auction links, provenance purchases `caused_by` the lot auction, exhibition venue/organizer metadata, exhibition-object `Set` links, concept influence, and travelling-exhibition `part_of` links. After MetaHistoryBook partner feedback, `/api/activity/collection` and `/api/activity/page/{page}` now add a first IIIF Change Discovery-compatible walk-back surface with a mandatory collection `last` link, fixed ascending `OrderedCollectionPage` resources, thin default activities, valid UTC page `endTime` values, dereferenceable MetaMuseum `object.id` URLs for record-backed rows, opt-in `embed=linked-art`, omitted absent `prev`/`next` links, `object.equivalent[]` reconciliation hooks synthesized from stored equivalents, provider URLs, and object Wikidata URLs, and declared-consumer telemetry for walk-back harvesters while preserving the cursor API as an extension. The partner test-ID rerun structurally passed; the first production-ID run then passed ordering, real timestamps, and dedupe but exposed the source-equivalent gap, so record detail responses now project both bare and HTTP stored IDs as canonical `/api/records/{encodedSourceRecordId}` URLs with `_links.self.href` alignment and source/Wikidata equivalents for strict Linked Art consumers. The July 5 `metahistorybook-harvester-prod` rerun passed all four validation points and is filed as first production-grade external-consumer harvest evidence; Daily&#39;s `daily-metahistorybook-prod` app read is filed as a second distinct product consumer and its callback is verified as the first durable subscription row; Wikidata Explorer&#39;s `wikidataexplorer-metamuseum-prod` walk-back read is filed as the third distinct external consumer with `53/53` Met `Create` activities and `47/53` QID mappings, and its callback is now verified by a real Met `Create` POST returning `202` plus a GET ledger showing QID `Q29385853`. The adoption matrix and partner onboarding pack now require a broad read plus explicit `type=Create`, `type=Update`, and `type=Delete` reads for each partner ID, keeping future partner evidence aligned with the strict activity-type coverage gate. Reviewed record metadata now emits real `reviewed-update` rows, with Met object `437133` live in production and partner-confirmed by MetaHistoryBook at `2026-07-05T19:50:30Z`; `pnpm activity:tombstone:scan` keeps a latest/run artifact for real upstream `404`/`410` monitoring and `pnpm activity:tombstone:evidence` still creates deletion rows only from real upstream `404`/`410` evidence refs. MetaHistoryBook signed callback proof is accepted with a real production `Create` Activity POST returning `204`, bringing durable callback evidence to `3/3`; strict proof now needs real `Delete` feed-read coverage. `Refresh` handling, stronger delivery guarantees, and real `Delete` observations remain follow-up compatibility/adoption work. Profile doc: linked-art/activity-stream-profile.md(linked-art/activity-stream-profile.md). Evidence: `tests/api/activity.test.ts`, `tests/api/activity-as2.test.ts`, `tests/api/records/by-id.test.ts`, linked-art/wikidataexplorer-consumer-evidence.md(linked-art/wikidataexplorer-consumer-evidence.md).</li><li>[x] ✅ <strong>Linked Art conservation activity proof (2026-07-06)</strong>: `/api/activity` now treats object-level `attributed_by` condition assessments as semantic `AttributeAssignment` `Update` rows, preserving `assigned_property`, `assigned` condition types, descriptions, timespan, actors, and conservation-project `part_of` links separately from `modified_by` conservation `Modification` rows with technique and intervention metadata. Evidence: `src/services/activity-feed.ts`, `tests/api/activity.test.ts`, linked-art/activity-stream-profile.md(linked-art/activity-stream-profile.md).</li><li>[x] ✅ <strong>Linked Art actor identity proof (2026-07-06)</strong>: `/api/records/{id}` now has regression coverage for rich `Person` and `Group` records from the People/Organizations pattern: name parts, authority `equivalent[]`, group membership, `contact_point` addresses/phone/email, residence `Place`, birth/death, formation, professional `carried_out` activity, burial `participated_in`, biography statements, and typed nationality/gender/occupation classifications stay as first-class Linked Art structures. Evidence: `tests/api/records/by-id.test.ts`.</li><li>[x] ✅ <strong>Linked Art place identity proof (2026-07-06)</strong>: `/api/records/{id}` now has regression coverage for the Places pattern: Place classifications, names, descriptions, `part_of` spatial hierarchy, authority `equivalent[]`, WKT `defined_by` geometry, approximate place nesting, and `HumanMadeObject.current_location` references to Places stay distinct so buildings/immovable objects are not coerced into Place records. Evidence: `tests/api/records/by-id.test.ts`.</li><li>[x] ✅ <strong>Linked Art concept identity proof (2026-07-06)</strong>: `/api/records/{id}` and `/api/concepts/{id}` now have regression coverage for the Concepts pattern: `Type`, `Material`, `Language`, `Currency`, and `MeasurementUnit` remain accepted concept classes; local concept records preserve primary names, AAT `equivalent[]`, `classified_as` meta-types, `broader` hierarchy, concept-scheme `member_of` Sets, coordinated concept `created_by.influenced_by`, and concept references with embedded equivalents without collapsing hierarchy, classification, and grouping. Evidence: `tests/api/records/by-id.test.ts`, `tests/api/entity-roles.test.ts`.</li><li>[x] ✅ <strong>Linked Art vocabulary-term proof (2026-07-06)</strong>: `/api/records/{id}` now has regression coverage for the vocabulary-term rule that classification terms may cite required/recommended/optional vocabulary URIs directly in `classified_as.id` or through an intermediary local term with the authority URI in `equivalent[]`. The fixture preserves both shapes exactly, so consumers can compare across institutions without Meta Museum flattening local terms or discarding Getty/AAT reconciliation anchors. Evidence: `tests/api/records/by-id.test.ts`.</li><li>[x] ✅ <strong>Linked Art required-term proof (2026-07-06)</strong>: `/api/records/{id}` now has regression coverage for the full Required Terms family when those concepts are modeled: primary/display/sort names, sort values, statement/type-of-work/style/shape/nationality/occupation/color meta-types, exhibition/provenance/professional/publication/promise activities, and collection-item/artwork flags all preserve the canonical full Getty AAT URIs instead of local substitutes. Evidence: `tests/api/records/by-id.test.ts`.</li><li>[x] ✅ <strong>Linked Art recommended-term proof (2026-07-06)</strong>: `/api/records/{id}` now has regression coverage for recommended vocabulary families as interoperability preferences rather than hard conformance failures: alternate/person-name parts, accession/local/system/call identifiers, statement categories with the Statement meta-type, object/place/group/digital/set/dimension classifications, language/unit/material/currency instances, nationality and occupation refinements with their meta-types, and shape terms with the Shape meta-type all preserve full Getty AAT URIs when modeled. Evidence: `tests/api/records/by-id.test.ts`.</li><li>[x] ✅ <strong>Linked Art optional-term proof (2026-07-06)</strong>: `/api/records/{id}` now has regression coverage for optional vocabulary families as mapping aids rather than requirements: translated titles, subtitles, aliases, pseudonyms, auction/ISBN/ISSN/DOI/stock identifiers, email/street/phone/fax contact points, optional statement and document classifications, optional place/group/object/object-part categories, and diameter/length/thickness dimensions all preserve full Getty AAT URIs when present. Evidence: `tests/api/records/by-id.test.ts`.</li><li>[x] ✅ <strong>Linked Art textual document proof (2026-07-06)</strong>: `/api/records/{id}` now has regression coverage for the Textual Documents pattern: physical book `HumanMadeObject` carriers preserve `carries -&gt; LinguisticObject` text links, textual content preserves monograph/chapter type classifications, primary and system identifiers, language, `content`, authorship `Creation`, publishing `Activity`, object `about` references, abstract-work `part_of` links, pagination statements, computable page-count dimensions, and `digitally_carried_by -&gt; DigitalObject` web-page carriers without collapsing copy, text, and digital surrogate layers. Evidence: `tests/api/records/by-id.test.ts`.</li><li>[x] ✅ <strong>Linked Art archival hierarchy proof (2026-07-06)</strong>: `/api/records/{id}` now has regression coverage for the Archival Hierarchies pattern: archive, archival grouping, and archival sub-grouping `Set` records preserve conceptual `member_of` hierarchy; archival `HumanMadeObject` letters and `DigitalObject` scans preserve their own `member_of` links; archival Sets use `members_contained_by` to align conceptual groups with physical boxes; item records use `held_or_supported_by` for actual physical containment; and `members_exemplified_by` preserves collective description without inventing inverse `member[]` lists. Evidence: `tests/api/records/by-id.test.ts`.</li><li>[x] ✅ <strong>Linked Art specific assertion proof (2026-07-06)</strong>: `/api/records/{id}` now has regression coverage for the Specific Assertions pattern: `AttributeAssignment` records preserve `assigned_property`, `assigned`, timespan, source/citation `used_specific_object`, context `caused_by`, uncertain production assignment details, embedded `Identifier`/`Name` `assigned_by` provenance, AI statement creation technique/tool metadata, statement-level rights, and generic related-entity display labels without replacing current canonical values. Evidence: `tests/api/records/by-id.test.ts`.</li><li>[x] ✅ <strong>Linked Art profile-boundary proof (2026-07-06)</strong>: `/api/records/{id}` now has regression coverage for the Profile design principle itself: baseline JSON-LD fields stay simple and predictable, including context, type, names, classifications, descriptions, equivalents, representations, and current production, while optional complexity is preserved as explicit `AttributeAssignment` expansion evidence with `assigned_property`, `assigned`, timespan, source, and review context. The fixture also keeps `_complete: false` and proves historical assertions do not overwrite current profile values. Evidence: `tests/api/records/by-id.test.ts`.</li><li>[x] ✅ <strong>Linked Art class-analysis proof (2026-07-06)</strong>: `/api/records/{id}` now has regression coverage for the Class Analysis guidance: public records use practical Linked Art classes such as `HumanMadeObject`, `LinguisticObject`, `VisualItem`, `DigitalObject`, `Name`, `Identifier`, `Set`, `Dimension`, `MeasurementUnit`, `Material`, `Right`, and `Group`, with collection/document/image/identifier specificity carried by `classified_as` terms where needed instead of raw CIDOC-CRM utility classes. A traversal assertion rejects leaked `E##` class names in the returned record graph. Evidence: `tests/api/records/by-id.test.ts`.</li><li>[x] ✅ <strong>Linked Art API reference docs section (2026-07-06)</strong>: linked-art/api/index.md(linked-art/api/index.md) now anchors a local Linked Art API 1.0 reference section for implementers and agents, with CC BY attribution, source URLs, endpoint summaries, field checklists, incoming relationship notes, Meta Museum coverage notes, and test ideas. The captured core endpoint notes cover Abstract Works(linked-art/api/abstract-works.md), Concepts(linked-art/api/concepts.md), Digital Objects(linked-art/api/digital-objects.md), Events(linked-art/api/events.md), Groups(linked-art/api/groups.md), People(linked-art/api/people.md), Physical Objects(linked-art/api/physical-objects.md), Places(linked-art/api/places.md), Provenance Activities(linked-art/api/provenance-activities.md), Sets(linked-art/api/sets.md), Textual Works(linked-art/api/textual-works.md), and Visual Works(linked-art/api/visual-works.md); JSON Schemas(linked-art/api/json-schemas.md) records the official endpoint schema catalog, Abstract Work required fields, and no-additional-properties validation target; Abstract Work Schema(linked-art/api/schema-abstract-work.md) records expanded `abstract.json` constraints for `PropositionalObject`, permitted top-level fields, embedded names/references/rights/visual/text structures, conceptual parent links, and `created_by` activity shape; Concept Schema(linked-art/api/schema-concept.md) records expanded `concept.json` constraints for `crm:E55_Type`, concept subclasses, embedded statements/representations, `created_by` activity shape, and `broader` hierarchy; Digital Object Schema(linked-art/api/schema-digital-object.md) records expanded `digital.json` constraints for `dig:D1_Digital_Object`, access points, media formats, conformance, digital services, carried/shown content, and `used_for`/`created_by` activity evidence; Event Schema(linked-art/api/schema-event.md) records expanded `event.json` constraints for `Period`/`Event`/`Activity`, timespans, places, temporal ordering, causation, actor responsibility, participants, techniques, and `part_of` references; Group Schema(linked-art/api/schema-group.md) records expanded `group.json` constraints for `crm:E74_Group`, group membership, performed/participated activities, contact points, residences, formation, and dissolution; Person Schema(linked-art/api/schema-person.md) records expanded `person.json` constraints for `crm:E21_Person`, group membership, performed/participated activities, contact points, residences, birth, and death; Physical Object Schema(linked-art/api/schema-physical-object.md) records expanded `object.json` constraints for `crm:E22_Human-Made_Object`, current ownership/custody/location, materials, parts, carrier/content/surrogate relationships, lifecycle activities, and provenance activities; Shared Structures(linked-art/api/shared-structures.md) records the embedded data-structure families, inherited-context behavior, and `_complete: false` dereference rule; Shared Activities(linked-art/api/shared-activities.md) records embedded activity classes, incoming relationship names, Birth/Death constraints, and activity `_complete: false` URI behavior; Shared Digital Links(linked-art/api/shared-digital-links.md) records nested work/digital-object links, `access_point`, service, format, and `conforms_to` behavior; Shared Dimensions(linked-art/api/shared-dimensions.md) records `Dimension` value/unit/type, uncertainty bounds, duration use, and `assigned_by` measurement evidence; Shared Concept References(linked-art/api/shared-concept-references.md) records allowed concept classes, notation, equivalent links, and concept meta-classification; Shared Identifiers(linked-art/api/shared-identifiers.md) records `Identifier` content, classification, notes, contact points, and assignment provenance; Shared Monetary Amounts(linked-art/api/shared-monetary-amounts.md) records `MonetaryAmount` value/currency/classification, uncertainty bounds, notes, `paid_amount`, and auction-lot dimension usage; Shared Names(linked-art/api/shared-names.md) records `Name` content, language tagging, nested parts, notes, and assignment provenance; Shared Rights(linked-art/api/shared-rights.md) records `Right` structures, license/right classifications, rights holders, statements, and `subject_to` usage; Shared References(linked-art/api/shared-references.md) records compact references, `equivalent`, `notation`, and the no-`_complete` reference rule; Shared Statements(linked-art/api/shared-statements.md) records embedded `LinguisticObject` content, language, labels, format, rights, creation evidence, and nested statements; Shared TimeSpans(linked-art/api/shared-timespans.md) records fuzzy boundary dates, duration dimensions, notes, and minimum content requirements; Shared Relationships(linked-art/api/shared-relationships.md) records `AttributeAssignment` relationship assertions, `assigned`, `assigned_property`, assignment provenance, and arbitrary related-entity links. `/api/docs/manifest` plus `/api/docs/content` have regression coverage proving the section is discoverable through the public docs surfaces. Evidence: `tests/utils/docs.test.ts`, `tests/api/docs.test.ts`.</li><li>[x] ✅ <strong>Endpoint-family schema enforcement slice</strong>: local Linked Art schema-profile validation now rejects unexpected top-level fields against endpoint-family allowlists for implemented families while permitting documented Meta Museum response metadata (`_links`, `schemaVersion`, `_source`), and a vendored official Linked Art schema JSON executor now checks the same aggregate endpoint-family fixtures for required fields, allowed fields, and `type` const/enum rules. Physical Object, Digital Object, Person, Group, Place, Concept subclasses (`Type`, `Material`, `Language`, `Currency`, `MeasurementUnit`), Event/Activity, Provenance Activity, Set, Textual Work, Visual Work, and Abstract Work pass/extra-field fail fixtures prove no-additional-properties behavior with local and official schema evidence. Recursive checks now cover endpoint-local Provenance Activity `part[]` structures and shared `core.json` structures, including nested Acquisition extra-field rejection, required `transferred_title_of` enforcement, embedded Name extra-field rejection, and required Name `content` enforcement. Evidence: `tests/quality/validation-architecture-depth.test.ts`(../tests/quality/validation-architecture-depth.test.ts).</li><li>[x] ✅ <strong>Linked Art graph partition planner</strong>: `src/utils/linked-art-partitioner.ts` now turns arbitrarily shaped but valid Linked Art graph input into discrete endpoint-family documents with first-class endpoint nodes emitted separately, compact references across document boundaries, owned embedded activity/shared structures preserved, `_complete: false` projected onto dereferenceable embedded summaries, recursion bounds for object parts, archival/set hierarchy, concept `broader`/`member_of`, and provenance `part[]` graphs, richer duplicate-node selection, and optional official schema validation on generated partitions. `/api/events/{id}` now uses the planner for ActivityStreams `linkedArt.id` dereferences, including activity subclasses such as `Production`, so event dereference responses keep object/agent relationships partition-bounded instead of recursively embedding record graphs. `/api/objects/{id}` now uses the planner for stored physical object records, bounding object `part` recursion while keeping owned lifecycle summaries such as `produced_by` embedded and their actor/place relationships compact. `/api/sets/{id}` and `/api/concepts/{id}` now use the same planner for stored Set and Concept hierarchy records, bounding `member`, `member_of`, and `broader` recursion while preserving the existing entity-index fallback for nested-only referenced sets/concepts. `/api/records/{id}` now runs record-detail serialization through the planner after canonical MetaMuseum id/equivalent projection, then adopts only recursive/root-activity planner fields so `_links.self`, `_source`, source equivalents, and rich record-detail embeddings stay stable. Evidence: `tests/utils/linked-art-partitioner.test.ts`(../tests/utils/linked-art-partitioner.test.ts), `tests/api/activity.test.ts`(../tests/api/activity.test.ts), `tests/api/entity-roles.test.ts`(../tests/api/entity-roles.test.ts), `tests/api/records/by-id.test.ts`(../tests/api/records/by-id.test.ts), linked-art/partitioning.md(linked-art/partitioning.md).</li><li>[x] ✅ <strong>Linked Art embedded completeness projection slice</strong>: `_complete: false` is now emitted automatically for partial dereferenceable embedded shared structures and activity nodes during record normalization and semantic ActivityStreams `linkedArt` projection, while compact references such as `equivalent`, `member_of`, and actor references remain reference-only without `_complete`. Evidence: `tests/utils/linked-art.test.ts`(../tests/utils/linked-art.test.ts), `tests/api/activity.test.ts`(../tests/api/activity.test.ts).</li><li>[x] ✅ <strong>Linked Art API design-principles reference (2026-07-06)</strong>: Design Principles(linked-art/api/design-principles.md) records the IIIF-derived API rules for shared use cases, internationalization, simplicity, REST/cacheability, JSON-LD, standards alignment, extensibility, networked retrieval, right-layer problem solving, one-direction relationship assertions, embedding, and opaque URI handling. Evidence: `tests/utils/docs.test.ts`, `tests/api/docs.test.ts`.</li><li>[x] ✅ <strong>Linked Art API JSON-LD considerations reference (2026-07-06)</strong>: JSON-LD Considerations(linked-art/api/json-ld-considerations.md) records the canonical Linked Art context, profile media type, case-sensitive terms, `id`/`type` aliases, always-array property discipline, scoped context naming, plain-JSON usability, and RDF compatibility checks for records, exports, and embedded `linkedArt` projections. Evidence: `tests/utils/docs.test.ts`, `tests/api/docs.test.ts`.</li><li>[x] ✅ <strong>Linked Art API protocol reference (2026-07-06)</strong>: Protocol(linked-art/api/protocol.md) records the HTTP(S) retrieval contract, required `GET`/`OPTIONS`, optional non-required `HEAD`, Linked Art JSON-LD content negotiation, wildcard CORS, future-version profile URI strategy, persistent URI practice, preferred endpoint names, and opaque URI handling. Evidence: `tests/utils/docs.test.ts`, `tests/api/docs.test.ts`.</li><li>[x] ✅ <strong>Linked Art API Search and Discovery captures (2026-07-07)</strong>: Search(linked-art/api/search.md) now records the HAL-driven inverse-discovery pattern, official `OrderedCollectionPage`/embedded `OrderedCollection` shape, `orderedItems`, `next`/`prev`, `startIndex`, and the current Meta Museum refinement target for normalizing local `nextPage`/`prevPage` compatibility fields toward official Search API pagination. Discovery(linked-art/api/discovery.md) now records HTML and HTTP `describedby` signposting, the exactly-one Linked Art record link rule, FAIR Signposting alignment, IIIF Change Discovery harvesting, Linked Art record-types context usage, and the current route-level refinement target for `Link: rel=&quot;describedby&quot;` headers. Evidence: `tests/utils/docs.test.ts`, `tests/api/docs.test.ts`, `tests/quality/data-discovery-signposting.test.ts`, `tests/quality/hal-search-relations-conformance.test.ts`.</li><li>[x] ✅ <strong>Linked Art canonical Search API pagination refinement (2026-07-07)</strong>: `/api/search` and `/api/relations/{relation}` now emit official `next`/`prev` `OrderedCollectionPage` link objects, `startIndex`, and `partOf.first`/`partOf.last` while preserving existing `nextPage`/`prevPage` compatibility fields. The relation fixture now proves a real next-page boundary with `objectOwnedByAgent&amp;limit=1`, and the shared HAL/search conformance helper checks official link-object shape without forcing every provider-specific legacy search route to migrate at once. Evidence: `tests/api/search.test.ts`, `tests/api/hal-relations.test.ts`, `tests/quality/hal-search-relations-conformance.test.ts`.</li><li>[x] ✅ <strong>Linked Art code-and-tools reference (2026-07-06)</strong>: Code And Tools(linked-art/api/code-and-tools.md) records implementation libraries, platforms, documentation/modeling aids, validators, visualization tools, and data-cleaning resources including Crom, LinkedArt.js, Linked.Art.Net, LUX, Arches, Ogee, Zellij, the Linked Art JSON Validator, Simple Dynamic Modelling, Mermaid, and OpenRefine. Evidence: `tests/utils/docs.test.ts`, `tests/api/docs.test.ts`.</li><li>[x] ✅ <strong>Linked Art bibliography reference (2026-07-06)</strong>: Bibliography(linked-art/api/bibliography.md) records scholarly and technical sources for Linked Art, LOUD, provenance, semantic annotation, image archives, community practice, and cross-collection discovery, with version-context guidance for using 2024-2025 sources for current claims and older entries for lineage/history. Evidence: `tests/utils/docs.test.ts`, `tests/api/docs.test.ts`.</li><li>[x] ✅ <strong>Linked Art CDWA mapping reference (2026-07-06)</strong>: CDWA Mapping(linked-art/api/cdwa-mapping.md) records the Getty CDWA-to-Linked-Art crosswalk for object, title, creation, measurement, materials, statement, activity, provenance, exhibition, visual documentation, textual reference, person/group, place, and concept authority fields, including explicit non-mappings for meta-metadata, Phase-like facts, and unsupported source fields. Evidence: `tests/utils/docs.test.ts`, `tests/api/docs.test.ts`.</li><li>[x] ✅ <strong>Linked Art Schema.org mapping reference (2026-07-06)</strong>: Schema.org Mapping(linked-art/api/schema-org-mapping.md) records derivative structured-data projection rules from canonical Linked Art into Schema.org for shared properties, people, organizations, places, concepts, human-made objects, digital objects, visual/textual works, events, and sets while keeping Linked Art as the source of truth. Evidence: `tests/utils/docs.test.ts`, `tests/api/docs.test.ts`.</li><li>[x] ✅ <strong>Linked Art Place schema reference (2026-07-06)</strong>: Place Schema(linked-art/api/schema-place.md) records expanded `place.json` constraints for `crm:E53_Place`, required identity fields, no-additional-properties validation, `defined_by` WKT/GeoJSON geometry, `part_of` spatial hierarchy, and incoming object/activity/actor place references. Evidence: `tests/utils/docs.test.ts`, `tests/api/docs.test.ts`.</li><li>[x] ✅ <strong>Linked Art Provenance Activity schema reference (2026-07-06)</strong>: Provenance Activity Schema(linked-art/api/schema-provenance-activity.md) records expanded `provenance.json` constraints for `crm:E7_Activity`, required identity fields, required provenance `classified_as`, no-additional-properties validation, temporal/activity context, and `part[]` evidence for acquisition, custody transfer, payment, encounter, movement, rights acquisition, and generic classified provenance activities. Evidence: `tests/utils/docs.test.ts`, `tests/api/docs.test.ts`.</li><li>[x] ✅ <strong>Linked Art Set schema reference (2026-07-06)</strong>: Set Schema(linked-art/api/schema-set.md) records expanded `set.json` constraints for `la:Set`, required identity fields, no-additional-properties validation, parent set hierarchy, physical member containers, exemplar member templates, topics, dimensions, and `used_for`/`created_by` activity evidence. Evidence: `tests/utils/docs.test.ts`, `tests/api/docs.test.ts`.</li><li>[x] ✅ <strong>Linked Art Textual Work schema reference (2026-07-06)</strong>: Textual Work Schema(linked-art/api/schema-textual-work.md) records expanded `text.json` constraints for `crm:E33_Linguistic_Object`, required identity fields, no-additional-properties validation, language, content, format, rights, aboutness, part relationships, and creation/use activity evidence while preserving carrier boundaries. Evidence: `tests/utils/docs.test.ts`, `tests/api/docs.test.ts`.</li><li>[x] ✅ <strong>Linked Art Visual Work schema reference (2026-07-06)</strong>: Visual Work Schema(linked-art/api/schema-visual-work.md) records expanded `image.json` constraints for `crm:E36_Visual_Item`, required identity fields, no-additional-properties validation, rights, dimensions, aboutness, represented entities, represented entity types, part/conceptual relationships, and creation/use activity evidence while preserving carrier boundaries. Evidence: `tests/utils/docs.test.ts`, `tests/api/docs.test.ts`.</li><li>[x] ✅ <strong>Linked Art event identity proof (2026-07-06)</strong>: `/api/records/{id}` and `/api/events/{id}` now have regression coverage for the Events pattern: `Period`, `Event`, and `Activity` records preserve names, timespans, places, actor responsibility, `caused_by`, strict `part_of` partitioning, contextual `during`, and relative `before`/`after` ordering, while object production/destruction references keep their temporal links instead of flattening them into dates. Evidence: `tests/api/records/by-id.test.ts`, `tests/api/entity-roles.test.ts`, `tests/api/activity.test.ts`.</li><li>[x] ✅ <strong>MetaHistoryBook Update/Delete alignment (2026-07-05)</strong>: after the accepted `204` callback proof, MetaHistoryBook first rechecked `type=Update` and `type=Delete` as explicit zeroes, then approved a two-ping plan. MetaMuseum deployed the real reviewed Met `437133` `Update` row, and MetaHistoryBook re-read `/api/activity?type=Update&amp;limit=100` as `metahistorybook-harvester-prod` at `2026-07-05T19:50:30Z`: `totalItems: 1`, `1` item, real non-synthetic, conformant `object.id`/`object.sourceId`/`equivalent[]`/UTC `endTime`, and cross-reconciliation through `Q432253`. `type=Delete` remains explicit zero by agreement until a genuine upstream `404`/`410` tombstone exists. Evidence: linked-art/metahistorybook-prod-harvest-evidence.md(linked-art/metahistorybook-prod-harvest-evidence.md).</li><li>[x] ✅ <strong>ActivityStreams partner quickstart (2026-07-04)</strong>: linked-art/activity-stream-partner-quickstart.md(linked-art/activity-stream-partner-quickstart.md) now gives external partners copy/paste feed-read, cursor sync, object-feed, subscription, verification, and response-template steps while explicitly stating the quickstart is not adoption evidence. `pnpm activity:partner-pack` links the quickstart and still emits `consumerIds: []`, placeholder rows, and `needs-consumer-ids` until real partner-owned IDs exist. Evidence: `tests/docs/activity-stream-partner-quickstart.test.ts`, `tests/scripts/activity-partner-onboarding-pack-script.test.ts`.</li><li>[x] ✅ <strong>MetaHistoryBook reciprocal harvest probe and rehearsal path (2026-07-05)</strong>: MetaHistoryBook now exposes a live IIIF Change Discovery stream, and Meta Museum has a bounded read-only probe at `pnpm activity:metahistorybook:harvest` that checks collection/page shape, fixed page size, oldest-first UTC `Update` activities, last-page walk-back start, dereferenceable Linked Art `object.id`, Wikidata `equivalent` reconciliation hooks, and the CC0 metadata `Link rel=license` header on both the collection and a sample record before any full-corpus import is considered. `pnpm activity:metahistorybook:import-rehearsal` adds the next rehearsal-only gate: capped page walk, capped record dereference sample, CC0 metadata-only rights mapping, QID mapping, and media-rights separation without adding a provider claim; after the partner approved moving the schedule forward, the latest larger rehearsal walked `562/562` pages, saw `56,196` activities, sampled `250/250` records, and mapped `250/250` metadata rights plus `250/250` QIDs. `pnpm activity:provider-backfill:evidence` now proves Meta Museum&#39;s own Met `record-backfill` publication rows separately from historic semantic events; the local gate covers `53` backfill rows, `53/53` real non-epoch timestamps, `53/53` equivalents, canonical MetaMuseum activity object IDs, and source/Wikidata equivalents synthesized for dereferenced records. MetaHistoryBook&#39;s July 5 production run as `metahistorybook-harvester-prod` passed multi-page ordering, real timestamps, `equivalent[]` reconciliation, and dedupe; it also proved the first concrete Met-to-MetaHistoryBook join on `Q432253` (`Garden at Sainte-Adresse`). Daily (`daily-metahistorybook-prod`) is filed as a second distinct external product consumer after walking the same 53 Met activities into an artwork-of-the-day candidate pool with 15 paintings and cursor `2026-05-31T10:40:54.290Z`; its public callback at `https://daily.metahistorybook.com/api/consumer/met/callback` now verifies for `Create`/`Update`/`Delete` and is filed as the first durable callback row. The rights mapping boundary is explicit: CC0 covers MetaHistoryBook&#39;s derived JSON metadata, while referenced image/media licenses remain separate. Checklist: linked-art/metahistorybook-reciprocal-harvest-checklist.md(linked-art/metahistorybook-reciprocal-harvest-checklist.md). Evidence: `docs/linked-art/metahistorybook-prod-harvest-evidence.md`, `artifacts/activity-syndication/daily-metahistorybook-prod-callback-2026-07-05.json`, `src/services/metahistorybook-harvest.ts`, `src/services/metahistorybook-import-rehearsal.ts`, `src/services/activity-provider-backfill-evidence.ts`, `tests/services/metahistorybook-harvest.test.ts`, `tests/services/metahistorybook-import-rehearsal.test.ts`, `tests/services/activity-provider-backfill-evidence.test.ts`, `tests/scripts/metahistorybook-harvest-probe-script.test.ts`.</li><li>[x] ✅ <strong>Activity discovery duplicate collapse (2026-07-05)</strong>: default `/api/activity/collection` and `/api/activity/page/{page}` responses now collapse duplicate rows for the same `object.id`, preferring deletion, audit, and `record-backfill` publication signals over historic `record-semantic` rows so walk-back harvesters see one latest-change item per object by default. Explicit `source=record-semantic` and `source=record-backfill` filters still expose source-specific rows for diagnostics and evidence checks. Evidence: `src/services/activity-feed.ts`, `app/api/activity/collection/route.ts`, `app/api/activity/page/[page]/route.ts`, `tests/api/activity-as2.test.ts`.</li><li>[x] ✅ <strong>Production activity backfill seed (2026-07-05)</strong>: external checks showed `www.metamuseum.org` had the latest activity code but only the single clean-deploy `record-003` seed, so `provider=met` and `source=record-backfill` returned `0` rows despite the local gate being green. `data/sample-records.json` now carries the 53 Met records needed for the public `record-backfill` corpus, and `tests/fixtures/production-seed-records.test.ts` guards the seed for 53 Met rows, real non-epoch `importedAt` values, and reconciliation/source hooks.</li><li>[x] ✅ <strong>External activity stream candidate registry (2026-07-05)</strong>: `/api/providers/capabilities` now exposes read-only standards-stream candidates separately from provider ingest claims: Getty IIIF Change Discovery is `probe-ready`, Rijksmuseum LDES is `route-available` via `/api/rijks/ldes`, and Europeana/CoGent LDES remain watchlist references. Candidate notes: linked-art/external-activity-streams.md(linked-art/external-activity-streams.md). Evidence: `src/services/external-activity-sources.ts`, `tests/services/external-activity-sources.test.ts`, `tests/api/providers/capabilities.test.ts`.</li><li>[x] ✅ <strong>ActivityStreams adoption controls</strong>: `src/services/activitystreams-adoption-controls.ts`(../src/services/activitystreams-adoption-controls.ts) and `tests/services/activitystreams-adoption-controls.test.ts`(../tests/services/activitystreams-adoption-controls.test.ts) now summarize and regression-check feed-read telemetry, partner-pack acceptance rows, durable HTTPS callback verification, strict review-goals selected checks, and placeholder/derived/local evidence rejection for the `0/3` real-consumer lane.</li><li>[x] ✅ <strong>Commercial readiness controls</strong>: `src/services/commercial-readiness-controls.ts`(../src/services/commercial-readiness-controls.ts) and `tests/services/commercial-readiness-controls.test.ts`(../tests/services/commercial-readiness-controls.test.ts) now summarize and regression-check the pre-revenue `/pilot` claim boundary, buyer-pack acceptance ledger, invoice-backed entitlement guard, monthly KPI/retention/gross-margin packet, and manual concierge versus repeatable subscription packaging gate.</li><li>[x] ✅ <strong>Security reliability controls</strong>: `src/services/security-reliability-controls.ts`(../src/services/security-reliability-controls.ts) and `tests/services/security-reliability-controls.test.ts`(../tests/services/security-reliability-controls.test.ts) now keep rotated-secret hygiene, production test-token rejection, membership-validated org-scope route coverage, and cron `CRON_SECRET` fail-closed behavior tied to one executable regression report.</li><li>[x] ✅ <strong>Testing gap controls</strong>: `src/services/testing-gap-controls.ts`(../src/services/testing-gap-controls.ts) and `tests/services/testing-gap-controls.test.ts`(../tests/services/testing-gap-controls.test.ts) now preserve complete onboarding coverage, scheduled disabled-feature drills, the `pnpm typecheck` release-command contract, storage-scope matrix breadth, and local-vs-strict evidence separation in one executable regression report, including acceptance-ledger links for every strict external contract and the no-global-bypass readiness downgrade.</li><li>[x] ✅ <strong>Complete onboarding e2e regression</strong>: `tests/e2e/onboarding-flow.test.ts`(../tests/e2e/onboarding-flow.test.ts) now walks the high-value launch path as one executable journey: public users hit the sign-in gate, a signed-in editor selects an active org, imports a provider record into org-scoped storage, creates an approval-required AgentTask review, approves a wiki draft, proves dry-run publication stays non-live, and exercises the publish-queue daily-cap boundary.</li><li>[x] ✅ <strong>Secret rotation preflight guard</strong>: production `pnpm launch:preflight:production` now requires non-secret rotation evidence and a git tracking/history probe for sensitive `.env*` files through `security.secretRotation` and `security.secretHistory`, and review-goals selects both rows as launch-readiness evidence.</li><li>[x] ✅ <strong>Secret evidence stale-artifact handoff</strong>: when an older `artifacts/launch/deployment-preflight-latest.json` is missing `security.secretRotation` or `security.secretHistory`, `pnpm review:goals` now reports the artifact as stale or missing current selected-check coverage, points to `pnpm launch:preflight:production`, and keeps the exact rotation/history acceptance criteria visible.</li><li>[x] ✅ <strong>Production preflight latest-artifact protection</strong>: `pnpm launch:preflight:production` now treats localhost/private production-target runs as diagnostics by keeping the timestamped run artifact while refusing to replace `deployment-preflight-latest.json`, so local `.env` defaults cannot accidentally become the review-goals launch evidence packet.</li><li>[x] ✅ <strong>Production launch-review public Era C handoff</strong>: production `pnpm launch:review:production` now points red or stale Era C evidence at `pnpm era-c:exit-gate:public` so operators refresh probe-backed public evidence instead of local telemetry, while staging review keeps `pnpm era-c:exit-gate:evidence` for rehearsal.</li><li>[x] ✅ <strong>Explicit-env production preflight mode</strong>: `METAMUSEUM_SKIP_ENV_FILES=1` now lets production evidence runs ignore local `.env*` files so staging-only values such as `METAMUSEUM_TEST_ROLE_OVERRIDE_TOKEN` cannot contaminate the public launch artifact. The latest explicit-env dry run proved the new `security.secretRotation` and `security.secretHistory` checks pass when non-secret rotation evidence and git history probes are supplied; strict `/api/validate` is now production-default closed unless `METAMUSEUM_STRICT_VALIDATION_PUBLIC=1` is set.</li><li>[x] ✅ <strong>Render strict-validation cold-start guard</strong>: `VALIDATION_TIMEOUT_MS` now bounds strict `/api/validate`, while production preflight keeps the long Render `/health` cold-start probe separate from user-facing readiness by treating Render validation as operator-only unless public strict validation is explicitly enabled. If `METAMUSEUM_STRICT_VALIDATION_PUBLIC=1` is set, preflight still fails without paid/no-sleep capacity evidence or within-budget health duration.</li><li>[x] ✅ <strong>TypeScript command drift retired</strong>: `pnpm typecheck` remains the CI-aligned production signal, while `pnpm typecheck:diagnostic` now converges with direct `tsc --noEmit`; `pnpm typecheck:diagnostic:report` writes JSON/Markdown parity artifacts with `status: converged`, `0` errors, `0` buckets, and `0` unclassified diagnostics. The command contract is in `docs/development/typescript-command-contract.md`(development/typescript-command-contract.md).</li><li>[x] ✅ <strong>Era A + Era B</strong>: legacy lift, parity, provider hardening, authority caching, B6.1 reconciliation, B7 gateway readiness/facade, B8 protocol conformance, B9 modeling guardrails, B10 ARK behavior, and pre-Era-C operational sign-off are complete.</li><li>[x] ✅ <strong>Era C implementation surface</strong>: C1-C5 core features are implemented, including multi-modal storage scaffolding, HAL/search/activity endpoints, C2 ETL/reconciliation/mapper, C3 IIIF + visualization surfaces, C4 AI query/chat/evals/mapping assist, specialized review agents, and C5 syndication/wiki/security/privacy hardening.</li><li>[x] ✅ <strong>AI agent review layer</strong>: five single-word field-aligned agents are live behind human approval: Clio (research signals), Mercator (Linked Art mapping review), Janus (reconciliation review), Themis (rights/provenance review), and Calliope (citation-backed curatorial drafts). Localhost smoke completed all five, avatar assets are verified, each returned AgentTask persists to editor-gated review history at `/api/agents/tasks`, and Mercator/Janus now have a disabled-by-default AG2 bridge boundary plus local review-only FastAPI worker with trace propagation, contract validation, timeout/refusal fallback, local fallback, safe enablement docs, and live-worker eval artifacts. AgentTask outputs now include reviewer-facing evidence diagnostics: Clio sparse-scope missing signals and next evidence, Mercator unmapped sensitive-column explanations, Janus reconciliation candidate-readiness plus zero-candidate reasons, Themis structured-rights/provenance evidence checks, and Calliope source-note citation-review snippets. `src/services/ai-agent-safety-controls.ts` and `tests/services/ai-agent-safety-controls.test.ts` now keep the safety posture executable across agent/model-spend RBAC, anonymous model downgrade, cite-or-refuse gates, approval-required AgentTask defaults, and opt-in AG2 bridge drills.</li><li>[x] ✅ <strong>Disabled-system staging drill</strong>: `pnpm staging:disabled-drill:check` now writes `artifacts/staging-disabled-systems/latest.json` and rehearses off-by-default AG2 fallback, enabled AG2 contract delegation with a mocked worker, Solr/GraphDB projection skip/no-network behavior, mocked enabled Solr/GraphDB request dispatch, projection readiness scale-pressure blockers, disabled cron no-ops, publication disabled-channel handling, and enabled publication webhook dispatch before those systems are enabled for real staging or production use; `.github/workflows/staging-disabled-systems-drill.yml` runs the same staging check weekly and uploads the latest/timestamped artifacts, with service, script, workflow, and testing-gap regressions asserting the expanded 9-check schedule contract.</li><li>[x] ✅ <strong>SEO/content publishing policy</strong>: generated article, book, object-label, and collection-brief outputs now include source-derived SEO metadata (`seoTitle`, meta description, primary/secondary keywords, H1, subheadings, slug, rationale) on both accepted and refused content paths; WikiDrafts validate the same SEO envelope while preserving canonical source titles and citation/originality gates.</li><li>[x] ✅ <strong>Security/privacy posture</strong>: PII/sensitivity scan, review holds, audited human disposition, rights/reuse UI warnings, and public projection controls are active before Solr/GraphDB syndication.</li><li>[x] ✅ <strong>Governance + docs contract</strong>: markdown under `docs/` remains the canonical source of truth, surfaced by `/docs`, `/api/docs/manifest`, and `/api/docs/content`; Linked Art reference mapping, AIDD/TDD, and closeout evidence remain mandatory. `pnpm product:constraints:check` now makes Linked Art conformance and rights-first publication non-negotiable by checking the generated conformance command/docs/tests, `Right` entity modeling, WikiDraft rights-warning publication guards, cite-or-refuse coverage, and human approval policy. `pnpm review:goals` now gives the 10/10 review-goal audit a blocker-preserving JSON and Markdown artifact, with each JSON artifact carrying a `$schema` pointer to `docs/schemas/review-goals.schema.json`, per-goal `evidenceArtifacts` paths, observed `evidenceArtifactStatuses`, selected `evidenceArtifactCheckStatuses`, structured per-goal `externalEvidenceBlockers`, and a flattened report-level blocker list for launch evidence/preflight/review checks, Render service probes, managed-pilot entitlement/outreach/activation/support/KPI evidence, long-term runway checks, Era C exit-gate `sota204P95`/`publicReadUptime`/`activityFeedAdoption`/`sota26Kpis` checks, ActivityStreams consumer/subscription checks, and paid-pilot proof. Those selected checks are readiness gates: local gates can be complete while real SLO, uptime, ActivityStreams consumer, KPI, and paid-pilot evidence remain explicitly external, no high-level flag can produce a 10/10 report while a selected artifact check is failing or missing, and bounded or fail-fast launch evidence still leaves a full packet behind with skipped remainder steps plus structured remediation, next evidence, command, and artifact fields preserved in the top-level audit. `SUPPORT.md` now gives contributors and operators an explicit issue, PR, security advisory, pilot evidence, launch blocker, and conformance escalation path without inventing an undocumented chat channel. The normal `pnpm session:closeout` path now refuses to append unless `README.md` and this roadmap were updated since the previous closeout.</li><li>[x] ✅ <strong>Deployment (LIVE)</strong>: the Next.js app is deployed to <strong>production on Vercel against Neon Postgres</strong> (`storageMode=postgres`), verified serving real records and public pages (2026-06-23). `vercel.json` pins `next build` so the close-out guard cannot break builds; the guard also self-skips when `VERCEL` is set. The `render.yaml` FastAPI validation and reconciliation services plus Redis cache are now deployed on Render, and both `/health` endpoints are included in launch readiness probes when their URLs are passed to `pnpm launch:evidence:production`. Secured Vercel Cron drains for outbox projection and publish queue processing are now configured at `/api/cron/outbox` and `/api/cron/publish`; both require `CRON_SECRET` and remain opt-in behind worker env flags until Solr/GraphDB projection or wiki/publication publishing is intentionally enabled. `/workers` and `/api/workers/status` now make scheduled-drain state explicit with worker lag, backlog, next cron wakeup, effective next drain, disabled projection/publish modes, and blocked/dead-letter signals. Direct Solr/GraphDB projection now also skips when target flags are unset, matching the read-only deploy contract. Deployment preflight now fails production when `BASE_URL` and `METAMUSEUM_PUBLIC_READ_BASE_URL` are missing, divergent, localhost, non-HTTPS, or otherwise not the same shareable public HTTPS URL, and runtime social metadata resolves against the public-read base before Vercel preview fallbacks. Documentation drift guards now keep Vercel/Neon launch examples aligned on the canonical public URL pairing and Neon `sslmode=verify-full`, including `.env.example`. Preflight now also probes live Auth.js `/api/auth/signin` and `/api/auth/session` routes so auth readiness is route evidence, not only secret presence, and fetches `IIIF_TILE_URL` so k6 tile evidence cannot point at a broken or protected target. Probe-based uptime history now keeps per-route URL, status, duration, and error/protection detail for public-read checks, making failed uptime samples and deployment-protection regressions diagnosable from the evidence artifact while the 30-sample window fills. `pnpm longterm:evidence` now records the daily 09:15 UTC collection cadence, next scheduled run, missing distinct SLO/uptime days, missing external-consumer count, and earliest possible ready date in the long-term evidence `collectionPlan`, so the 30-day blocker has an operator-visible runway instead of a vague wait state. Optional Render validation/reconciliation dependencies are now explicit in deployment preflight: unset URLs record the local fallback/in-process mode, while configured service URLs get `/health` status and duration evidence so cold starts and timeouts are visible in launch readiness artifacts. `pnpm activity:syndication:evidence` now ties real declared external ActivityStreams consumers to active external HTTPS subscriptions for the same IDs, keeps accepted/rejected callback rows in the artifact, and counts only public non-placeholder callback hosts that match their HTTPS callback URL, were updated inside the evidence window, cover Create/Update/Delete, and carry recent 2xx callback verification proof, keeping durable syndication blocked until partner callback workflows are fresh, complete, and verified. `pnpm smoke:crawler-preview` now records Facebook, Slack, Googlebot, LinkedIn, and X/Twitter-facing Open Graph/Twitter/canonical checks plus preview image fetchability in launch artifacts. `pnpm launch:evidence` and `pnpm launch:evidence:production` now run hardening security/DR, preflight, public trust, crawler preview, a11y, explore, k6, Era C exit-gate, and launch review as one blocker-preserving evidence packet, and failed/skipped steps name the remediation command plus artifact path operators should turn green next. The route-storage guard now walks production API import paths and blocks unmanaged local JSON writes; activity subscriptions, AI query usage logs, issue cache, and publish queue persistence are Postgres-managed documents instead of Vercel filesystem writes. See deployment.md(deployment.md).</li><li>[x] ✅ <strong>Review-goals version 44 consent posture gate</strong>: `pnpm privacy:consent:check` now writes `artifacts/privacy/analytics-consent-latest.json`, and review goals include the GA4 consent posture as a governance goal with local script, docs, tests, and artifact checks.</li><li>[x] ✅ <strong>Review-goals version 42 scoped blocked-goal actions</strong>: `blockedByExternalEvidenceGoals[].scopeBreakdown[].nextActionIds` now lets each blocked-goal scope join directly to grouped remediation actions.</li><li>[x] ✅ <strong>Review-goals version 41 blocked-goal scope counts</strong>: `blockedByExternalEvidenceGoals[].scopeCount` now exposes how many execution lanes remain for each named blocked goal.</li><li>[x] ✅ <strong>Review-goals version 40 blocked-goal totals</strong>: `blockedByExternalEvidenceGoals[].actionCount`, `commandCount`, and `artifactCount` now expose dashboard-ready blocked-goal handoff totals directly.</li><li>[x] ✅ <strong>Review-goals version 39 blocked-goal requirements</strong>: `blockedByExternalEvidenceGoals[].nextEvidenceRequirements` and `requirementCount` now make each named blocked goal self-contained with exact acceptance criteria.</li><li>[x] ✅ <strong>Review-goals version 38 external blocker actions</strong>: `externalEvidenceBlockerSummary[].nextActionIds` and `actionCount` now point each blocker lane directly at grouped remediation actions.</li><li>[x] ✅ <strong>Review-goals version 37 external blocker requirements</strong>: `externalEvidenceBlockerSummary[].nextEvidenceRequirements` and `requirementCount` now expose acceptance criteria directly per blocker lane.</li><li>[x] ✅ <strong>Review-goals version 36 action-summary counts</strong>: `nextActionSummary[].actionCount` now exposes action totals per execution-scope lane while legacy `count` remains for compatibility.</li><li>[x] ✅ <strong>Review-goals version 35 strict action counts</strong>: `strictGateHandoff.nextActionCount` and scoped `strictGateHandoff.scopeBreakdown[].nextActionCount` now expose executable action totals directly, so dashboards do not have to count action ID arrays.</li><li>[x] ✅ <strong>Review-goals version 34 blocked-goal scoped payloads</strong>: `blockedByExternalEvidenceGoals[].scopeBreakdown[]` now includes scoped remediation commands, artifact targets, and next-evidence requirements, so each named blocked goal can be handed to an operator without joining through action rows.</li><li>[x] ✅ <strong>Review-goals version 33 blocked-goal scope counts</strong>: `blockedByExternalEvidenceGoals[].scopeBreakdown[]` now exposes action, command, artifact, and requirement counts per scope, so each named blocked goal carries dashboard-ready handoff totals without parsing nested arrays.</li><li>[x] ✅ <strong>Review-goals version 32 strict requirement counts</strong>: `strictGateHandoff.requirementCount` and scoped `strictGateHandoff.scopeBreakdown[].requirementCount` now expose distinct next-evidence acceptance-criteria totals directly, so dashboards can show how many criteria remain without parsing long requirement text.</li><li>[x] ✅ <strong>Review-goals version 31 strict artifact counts</strong>: `strictGateHandoff.artifactCount` and scoped `strictGateHandoff.scopeBreakdown[].artifactCount` now expose distinct evidence-artifact target totals directly, so dashboards do not have to count artifact arrays before showing the remaining evidence packet footprint.</li><li>[x] ✅ <strong>Review-goals version 30 strict command counts</strong>: `strictGateHandoff.commandCount` and scoped `strictGateHandoff.scopeBreakdown[].commandCount` now expose distinct remediation-command totals directly, so dashboards do not have to count command arrays or confuse distinct commands with scoped action rows.</li><li>[x] ✅ <strong>Review-goals version 29 strict goal counts</strong>: `strictGateHandoff.goalCount` and scoped `strictGateHandoff.scopeBreakdown[].goalCount` now expose affected-goal totals directly, so dashboards do not need to count goal arrays.</li><li>[x] ✅ <strong>Review-goals version 28 strict action IDs</strong>: `strictGateHandoff.nextActionIds[]` and scoped `strictGateHandoff.scopeBreakdown[].nextActionIds[]` now point from the strict-gate handoff directly to the executable `nextActions[]` rows, so operators do not have to reconstruct command/scope keys.</li><li>[x] ✅ <strong>Review-goals version 27 strict blocker IDs</strong>: `strictGateHandoff.blockerIds[]` and scoped `strictGateHandoff.scopeBreakdown[].blockerIds[]` now name the exact failing checks behind the strict gate, so operators can trace a blocker directly to the artifact/check row without joining through goals.</li><li>[x] ✅ <strong>Review-goals version 26 strict scope breakdown</strong>: `strictGateHandoff.scopeBreakdown[]` now splits strict-gate commands, artifacts, affected goals, blocker counts, and next-evidence requirements by execution scope, so deployment setup and real-world proof cannot be merged in the final operator handoff.</li><li>[x] ✅ <strong>Review-goals version 25 strict evidence requirements</strong>: `strictGateHandoff.nextEvidenceRequirements[]` now unions the exact next-evidence sentences from scoped action rows, so the strict-gate handoff carries the commands, artifact paths, and evidence acceptance criteria together.</li><li>[x] ✅ <strong>Review-goals version 24 strict handoff</strong>: `strictGateHandoff` now consolidates strict-gate summary IDs, execution scopes, blocker count, affected goals, remediation commands, and artifact targets into one schema-locked operator payload, so launch dashboards can show remaining deployment and real-world proof without rejoining summary rows.</li><li>[x] ✅ <strong>Review-goals version 23 strict summary invariants</strong>: runtime invariants now validate every structured `strictGateFailureSummary[]` field against the derived blocker summaries, so strict-gate dashboard rows cannot silently drift in counts, goals, commands, artifacts, scope, kind, or reason text.</li><li>[x] ✅ <strong>Review-goals version 22 structured strict failure summary</strong>: `strictGateFailureSummary[]` now gives dashboards closed rows with kind, scope, blocker counts, affected goals, commands, artifacts, and the matching reason, so deployment-environment and real-world evidence lanes can be consumed without parsing prose.</li><li>[x] ✅ <strong>Review-goals version 21 strict failure reasons</strong>: `strictGateFailureReasons[]` now lists the non-empty blocker lanes and remediation commands when the strict 10/10 gate fails, so local-green reports explain the remaining deployment and real-world evidence work directly in JSON and Markdown.</li><li>[x] ✅ <strong>Review-goals version 20 strict gate status</strong>: `strictGateStatus` now records the final `pnpm review:goals:check` pass/fail result separately from `localGateStatus`, so local-green reports with remaining production, partner, customer, or 30-day evidence blockers cannot be misread as 10/10-ready.</li><li>[x] ✅ <strong>Review-goals version 16 handoff shape</strong>: `nextActionSummary[]` now carries distinct commands, artifact targets, goal IDs, titles, categories, and counts per execution scope, so the deployment-environment and real-world-evidence lanes show which 10/10 goals they affect and which outputs they refresh without requiring dashboards or operators to join through `nextActions`.</li><li>[x] ✅ <strong>Review-goals version 17 blocker scopes</strong>: goal-level and report-level external-evidence blocker rows now carry `executionScope` directly, so each blocker is visibly `deployment-environment` or `real-world-evidence` at the row level instead of requiring a join through `nextActions`.</li><li>[x] ✅ <strong>Review-goals version 19 scoped actions</strong>: `nextActions[]` now groups by remediation command plus execution scope, so shared commands such as `pnpm era-c:exit-gate:evidence` can produce separate deployment-environment and real-world-evidence action rows instead of mixing blocker lanes.</li><li>[x] ✅ <strong>Review-goals version 18 blocker summaries</strong>: `externalEvidenceBlockerSummary[]` now groups raw blocker rows by execution scope with blocker IDs, goals, remediation commands, and artifact targets, so deployment and real-world blocker debt remains visible even before operators inspect grouped actions.</li><li>[x] ✅ <strong>Review-goals invariant guard</strong>: the CLI now refuses to write malformed review-goals artifacts when score totals, blocked-goal counts, blocker counts, unknown action references, scope summaries, commands, artifact targets, or goal lists drift from the generated report body.</li><li>[x] ✅ <strong>Review-goals version alignment</strong>: `REVIEW_GOALS_REPORT_VERSION`, emitted report `version`, and JSON schema `version.const` are test-locked together so artifact contract bumps cannot split the service and schema.</li><li>[x] ✅ <strong>Review-goals schema parity guard</strong>: generated JSON artifacts are runtime-validated against the schema-required keys and closed-object sections for report, score, goal, evidence, blocked-goal, action, and action-summary rows before the CLI prints or writes them, so schema/report drift fails before operators receive a malformed 10/10 evidence handoff.</li><li>[x] ✅ <strong>Portfolio README + docs (2026-06-24)</strong>: README trimmed from ~1,300 lines to a lean hero + highlights + run-it + honest &quot;what&#39;s real vs. in progress&quot; (detailed status stays here in the roadmap). New deep-dives added: responsible-ai.md(responsible-ai.md) (key handling, denial-of-wallet auth-gate, citation/refusal gates, eval harness, cost control) and linked-art/conformance-matrix.md(linked-art/conformance-matrix.md) (protocol MUSTs verified live + per-provider matrix + honest gaps). A single-file architecture/reviewer HTML handoff is maintained at metamuseum-project-overview.html(metamuseum-project-overview.html) for browser-openable reviewer context.</li><li>[x] ✅ <strong>README density refresh (2026-06-28)</strong>: the README no longer carries the long review-goals artifact-version history or operator-level schema prose; it now gives fast reviewers a short strict-readiness summary and links to docs/ops/review-goals.md(ops/review-goals.md) for the detailed artifact contract.</li><li>[x] ✅ <strong>Linked Art rights as `Right` entities — all providers (2026-06-24)</strong>: started the roadmap to 10/10(roadmap-to-10.md) with milestone <strong>B1</strong>. `src/utils/linked-art-rights.ts` synthesizes a conformant `subject_to` `Right` (classified by CC0 / rightsstatements.org URIs) for every object record that lacks one, wired into both `normalizeIncomingRecord` and the read-path `migrateToCurrentSchema`; Getty&#39;s are preserved. Closes the &quot;rights as labels outside Getty&quot; gap in the conformance matrix.</li><li>[x] ✅ <strong>Reliable, badged CI — roadmap-to-10 A1 (2026-06-24)</strong>: the session close-out guard no longer fails CI — `scripts/session-closeout.ts` skips the `--check` guard when `CI` is set (it stays enforced locally), so a stale local close-out log can&#39;t turn a green build red (the PR #16 failure mode). README header now carries CI / License / Linked Art / tests badges, and the tests badge intentionally uses a guarded `1,100+` label rather than an exact stale-prone count.</li><li>[x] ✅ <strong>Supply-chain hygiene — roadmap-to-10 A2 (2026-06-24)</strong>: resolved all 3 moderate `pnpm audit --prod` advisories via `pnpm.overrides` (postcss XSS → `&gt;=8.5.10`; OpenTelemetry memory-DoS → core/resources/sdk-trace-base `^2.8.0`, which also fixes `@vercel/otel`&#39;s mis-resolved 1.30.1 peers). Added `.github/dependabot.yml` (npm + github-actions + 4 pip services) and a `pnpm audit --prod --audit-level high` CI gate. Audit clean; tests 1,114; build green.</li><li>[x] ✅ <strong>Per-provider conformance matrix generated — roadmap-to-10 B3 (2026-06-24)</strong>: the 14×2 per-provider pass/fail fixtures (asserted in CI by `validation-architecture-depth.test.ts`) now drive a <strong>generated</strong> conformance matrix via `scripts/generate-conformance-matrix.ts` (`pnpm conformance:matrix`); `conformance-matrix-generated.test.ts` gates drift. The published `conformance-matrix.md` table is no longer hand-maintained. 14/14 providers pass both directions.</li><li>[x] ✅ <strong>SHACL conformance gate in CI — roadmap-to-10 B2 (2026-06-24)</strong>: `services/validation-service/shacl_gate.py` + `.github/workflows/shacl-conformance.yml` validate every provider&#39;s pass fixture against the Linked Art SHACL shapes with pyshacl (JSON-LD → CIDOC-CRM RDF). Path-filtered job; `pnpm shacl:gate` locally. All 14 pass fixtures conform; a CRM-expansion regression now blocks the build.</li><li>[x] ✅ <strong>Measured + gated test coverage — roadmap-to-10 A3 (2026-06-24)</strong>: `pnpm test:coverage` runs the suite under c8 with a `--check-coverage` gate (lines 85 / funcs 85 / branches 70); CI&#39;s test step now enforces it. Current 89.4% lines / 92.1% funcs (core `src/services` 91.9%). README coverage badge added; also fixed CRLF-fragility in the B3 drift test so coverage runs clean cross-platform.</li><li>[x] ✅ <strong>Published quality scores — roadmap-to-10 A4 (2026-06-24)</strong>: `docs/quality.md`(quality.md) publishes CI-measured numbers — Lighthouse a11y <strong>100/100</strong> on key pages, axe <strong>0 severe</strong> WCAG 2A/2AA violations across 18 routes, and the k6 p95 performance budget <strong>met</strong> (cached 73.5 ms, cold 56.1 ms, facet 55.1 ms, 0% errors). README a11y badge added.</li><li>[x] ✅ <strong>Faceted / relevance search — roadmap-to-10 B4 (2026-06-24)</strong>: `src/services/search.ts` ranks `/api/search` results by hit quality (exact label &gt; prefix &gt; substring &gt; name) and returns `type`/`provider` facet counts + `q`/`type`/`provider`/`limit`/`offset` params in the `ld+json` `OrderedCollectionPage`. Tested at the service + API level; conformance-matrix &quot;basic, not faceted&quot; gap closed (Solr 9 documented as the env-gated scale backend).</li><li>[x] ✅ <strong>Fixed flaky annotations test / CI reliability (2026-06-24)</strong>: annotation ids were `annotation-${Date.now()}`, so two creates in the same millisecond shared an id — letting annotations in different org scopes collide and intermittently breaking the cross-org isolation assertion in CI. Centralized id minting in `mintAnnotationId()` (timestamp + `randomUUID`); added a deterministic 1,000-mint uniqueness test. Completes the A1 &quot;reliable CI&quot; goal.</li><li>[x] ✅ <strong>HEAD + HTTP/2 conformance — roadmap-to-10 B6 (2026-06-24)</strong>: the canonical Linked Art entity/collection routes now export `HEAD` (via a `bodilessResponse(await GET(...))` helper in `src/utils/protocol.ts`) — same headers as GET, no body, mirrors 200/404; `OPTIONS` advertises `GET,HEAD,OPTIONS`. HTTP/2 verified live (`HTTP/2.0 200` via Vercel). `tests/api/head-methods.test.ts`; suite 1,128.</li><li>[x] ✅ <strong>Roadmap trimmed — roadmap-to-10 A5 (2026-06-24)</strong>: this roadmap went from ~1,510 lines to ~420 by archiving the slice-by-slice Era A/B/C history to `progress/era-history.md`(progress/era-history.md) (see &quot;Era delivery history&quot; below). `getStructuredRoadmap` aggregates both files so `/api/roadmap` still exposes full phases/milestones.</li><li>[x] ✅ <strong>Activity Streams change feed — roadmap-to-10 B5 (2026-06-24, lifted 2026-07-04)</strong>: aligned `/api/activity` to Activity Streams 2.0 — AS2 `@context`, cursor-first `next`/`prev` page links (kept offset `nextPage`/`prevPage` aliases), a fuller `partOf` `OrderedCollection` with `first`/`last`/`totalItems`, `application/activity+json`, embedded Linked Art projections, semantic record-event extraction, filters, cursor sync, and object-scoped feeds. `tests/api/activity-as2.test.ts`, `tests/api/activity.test.ts`.</li><li>[x] ✅ <strong>Product walkthrough + evaluator brief — roadmap-to-10 A6 (2026-06-29)</strong>: the README now links a recorded no-narration public-site walkthrough at `public/media/metamuseum-product-walkthrough.webm`(../public/media/metamuseum-product-walkthrough.webm), `/projects` presents it as a professional Linked Art SaaS product case study, and the shot-by-shot replacement script remains at `demo-script.md`(demo-script.md). The current 10/10 gate is no longer a demo-media checklist; `pnpm review:goals:check` remains blocked on the launch-review Era C dependency, paid-pilot proof, 30-day SLO/uptime evidence, KPI exports, and durable ActivityStreams syndication.</li><li>[x] ✅ <strong>Product case-study layout pass (2026-06-29)</strong>: `/projects` now gives the CTA row, proof strip, case-study cards, architecture cards, and walkthrough media page-specific spacing and wrapping so buttons and cards do not touch or overlap across mobile, tablet, and desktop checks.</li><li>[x] ✅ <strong>Standalone project overview HTML (2026-06-29)</strong>: `metamuseum-project-overview.html`(metamuseum-project-overview.html) now provides a single-file, browser-openable project overview with inline CSS/SVG only, covering essence, architecture, components, engineering discipline, state, risks, and evidence-based next improvements.</li><li>[x] ✅ <strong>Dependency batch verified (2026-06-24)</strong>: applied all 14 open Dependabot updates in one verified PR (#48) — fastapi 0.138, pyld 3.1, redis 8, pydantic 2.13, dagster 1.13.10, `actions/checkout` 6→7 — each installed in a clean venv and run against the relevant service&#39;s tests (validation `validate_record` + SHACL gate, reconciliation 9 tests, ag2-worker 6 tests, pipeline 3 tests). SHACL CI pins synced; queue cleared. Keeps A2 supply-chain hygiene current.</li><li>[ ] ⚠️ <strong>Era C exit gate is not green yet</strong>: latest evidence is still `failed`. The current strict handoff reports `20/30` retained deployed SLO samples across `7/30` observed days, with `13/30` passing samples across `6/30` passing days and `7` failed/incomplete retained rows. Public-read uptime has `126/129` passing retained checks across `10/30` observed days but only `0.9767` availability against the `0.999` target, ActivityStreams has `3/3` declared external consumers, restored `3/3` durable callback rows, and observed `Create, Update` type coverage while still missing real `Delete` read coverage, and production KPI exports still miss reconciliation thresholds. The project is strong for controlled beta/demo use, but not yet ready to claim full public-production completion.</li></ul>\n<ul><li>[x] ✅ <strong>Worker scale scheduler guard (2026-06-27)</strong>: production preflight now fails if Solr/GraphDB projection targets are enabled without `CRON_SECRET` plus `METAMUSEUM_OUTBOX_CRON_ENABLED=1`, or if live MediaWiki/Wikibase endpoints or bot tokens are configured without `CRON_SECRET` plus `METAMUSEUM_PUBLISH_QUEUE_CRON_ENABLED=1`. A static Vercel config test also keeps `/api/cron/outbox` and `/api/cron/publish` scheduled before those scale flags can be treated as launch-ready.</li><li>[x] ✅ <strong>Vercel Observability cron-error fix (2026-06-28)</strong>: live probes showed `/api/cron/outbox` and `/api/cron/publish` returning `503 cron_secret_missing` while `/api/workers/status` showed both drains intentionally disabled. Disabled scheduled drains now return `200` no-op JSON without `CRON_SECRET`, while enabled drains still require bearer auth before any outbox or publish work can run; route-level tests cover the disabled no-op and enabled-secret cases.</li><li>[x] ✅ <strong>Projection scale-readiness gate (2026-06-27)</strong>: `pnpm projection:readiness` now writes `artifacts/launch/projection-readiness-latest.json` and classifies Solr/GraphDB projection as `portable`, `watch`, `enable`, or `enabled` based on current record count, active discovery/graph workflow counts, and search/graph p95 metrics. `pnpm projection:readiness:check` exits non-zero when the scale path is required but target/scheduler readiness is incomplete, so Solr/GraphDB projection is enabled only when volume and discovery workflows justify it.</li></ul>\n<h3 id=\"current-launch-readiness\">Current Launch Readiness</h3>\n<p>| Launch lane | Score | Current decision | Required next evidence |</p>\n<p>|---|---:|---|---|</p>\n<p>| Internal/dev demo | 9/10 | Safe to keep using and iterating locally. | Keep `pnpm test`, `pnpm lint`, `pnpm build`, and closeout guard green. |</p>\n<p>| Controlled public beta | 8.4/10 | App is now <strong>live on Vercel + Neon</strong> at `https://www.metamuseum.org` (2026-06-23), clearing the deployed-base-URL blocker. The July 3 production preflight passes `20/20`: OAuth, Postgres storage shape, `sslmode=verify-full`, live Neon authentication, active deployment freshness after secret rotation, auth/IIIF reachability, validation/reconciliation Render `/health` probes, public-read reachability, social-preview base URL parity, no production smoke override token, and secret-rotation/history evidence all pass. Strict `/api/validate` is operator-only by default in production unless `METAMUSEUM_STRICT_VALIDATION_PUBLIC=1` is set. The refreshed launch evidence packet passes `8/9`, launch review passes `7/8`, and controlled beta remains blocked only because the Era C row still needs 30-day SLO/uptime, ActivityStreams, and KPI proof. | Keep `pnpm launch:evidence:production`, `pnpm launch:review:production`, and `pnpm launch:beta:readiness` fresh with production env present; controlled beta can advance further once Era C has enough SLO, uptime, adoption, and KPI evidence or an explicit narrower beta acceptance policy is recorded. |</p>\n<p>| General public production | 6.5/10 | Not yet; product is feature-rich but evidence gates are red. | Passing 30-day SLO/uptime evidence, real KPI telemetry, and external activity-feed adoption proof. |</p>\n<p>| Institution-grade / 10/10 | 5.5-6/10 | Blocked by time-based evidence and real-world adoption. | At least 30 days of green SLO + uptime samples, 3 declared external feed consumers, and SOTA §26 KPI targets. |</p>\n<h3 id=\"current-saas-readiness\">Current SaaS Readiness</h3>\n<p>| SaaS lane | Score | Current decision | Required next evidence |</p>\n<p>|---|---:|---|---|</p>\n<p>| Technical SaaS foundation | 7/10 | Strong enough to begin SaaS packaging: auth, roles, Postgres storage, provider ingestion, validation, docs, launch review, and trust/syndication tooling are real. | Complete staging secrets, production-like deployment, usage limits, tenant-aware data boundaries, and supportable onboarding. |</p>\n<p>| Paid pilot readiness | 8.2/10 | Close for 1-3 concierge pilots where Sun &amp; Rain Works can manually onboard collections and invoice outside the app; `/pilot` is shared-nav reachable and publishes the offer, commercial-readiness ledger showing `0` paid pilots, manual invoice entitlement path, and in-app billing not built, named initial outreach queue, derived status ledger showing 13 researched accounts, 1 sent message, and 0 replies, and a zero-complete activation evidence ledger backed by managed outreach and activation events with the next required evidence. The queue includes Museum of New Zealand Te Papa Tongarewa, Museums Victoria, and Art Gallery of Ontario; Te Papa web-form outreach is recorded at `2026-07-04T18:30:00.000Z` from the user&#39;s reported July 4, 2026 11:30 AM Pacific submission, while no reply, invoice, or buyer activation is claimed. `pnpm pilot:buyer-pack` gives buyer-ready packs acceptance rows for outreach, invoice-backed entitlement, activation, support load, required KPIs, retention signal, gross-margin proof, and strict packet refresh, with the support-load row now verifying through `pnpm pilot:support -- --tenant &lt;tenant-id&gt; --summary`; `pnpm pilot:outreach`, `pnpm pilot:activation`, `pnpm pilot:support`, and `pnpm pilot:evidence --markdown` give operators validated no-JSON-edit commands for recording real first-outreach/milestone/support evidence and packaging explicit blocked/ready JSON plus Markdown evidence artifacts. `pnpm pilot:evidence --check` exits non-zero for blocked packets while still writing artifacts, so missing real entitlement, activation, support load after real pilot activity, KPI, retention, or gross-margin proof cannot pass automated readiness silently. Outreach replies require prior sent evidence, sent follow-up dates are barred from predating `sentAt`, activation milestones require prior same-tenant evidence, tenant-mismatched activation evidence is rejected, support response and resolution timestamps are barred from predating `openedAt`, existing support issue updates are barred from rewriting the original `requester`, `summary`, `openedAt`, or `severity`, already-resolved support issue updates are barred from rewriting `resolvedAt` or `resolutionSummary`, open support issues are barred from carrying resolution evidence, and support-load evidence remains blocked until an invoice-backed pilot has `pilot.support_minutes` evidence plus no open blocking or overdue support responses. `docs/ops/managed-linked-art-pilot-runbook.md` defines the concierge setup, tenant/source namespace, activation events, support intake, monthly evidence packet, and counter-backed route usage gate; `src/services/pilot-entitlements.ts`, `src/services/pilot-usage-counters.ts`, `src/services/pilot-support-issues.ts`, org storage scope, tenant preview scope, and route gates keep the manual pilot lane durable, org-aware, quota-gated, and exportable without implying self-serve billing readiness. | Follow up on Te Papa if they reply, sign one manual pilot scope, create an invoice-referenced entitlement, onboard one real pilot dataset using the runbook, attach deployment-specific security/legal evidence to the buyer packet, complete the buyer-pack acceptance rows with real tenant evidence, add route-level support-access implementation tests only if a support-as-customer feature ships, and complete activation, support, KPI, retention, and gross-margin ledgers with real tenant evidence. |</p>\n<p>| Self-serve SaaS readiness | 3/10 | Not ready; the app lacks pricing pages, tenant signup, billing, plan gates, org invites, usage dashboards, and support workflows. | Add account/org onboarding, billing/manual-plan entitlements, quotas, usage analytics, and customer success runbooks. |</p>\n<p>| Profitable SaaS business | 4/10 | The product has a credible technical wedge, but revenue operations and repeatable sales motion are not proven yet. | Convert paid pilots into recurring subscriptions with gross-margin, retention, support-load, and acquisition-channel evidence. |</p>\n<p>Pilot packets now expose `commercial.billing`, `commercial.retention`, and `commercial.grossMargin` evidence directly. `pnpm review:goals` treats invoice-backed billing, `pilot.retention_signal_count`, and `pilot.gross_margin_percent` as selected checks, so managed-pilot readiness cannot pass from activation/support/KPI proof alone. `src/services/commercial-readiness-controls.ts` keeps the public pre-revenue copy, buyer-pack rows, invoice guard, monthly packet, and packaging gate in one executable report while real paid-pilot evidence remains missing.</p>\n<h3 id=\"saas-commercialization-strategy\">SaaS Commercialization Strategy</h3>\n<p><strong>Primary wedge:</strong> managed Linked Art API + data-quality cockpit for small/mid-size museums, archives, galleries, digital humanities labs, and artist estates that want standards-compliant publication without hiring a semantic-web team. This wedge matches the current product surface best: provider ingestion, Linked Art normalization, API/docs, validation, public trust, AI query, reconciliation, IIIF, ActivityStreams, and Neon-backed storage.</p>\n<p><strong>Secondary wedge, defer until the B2B pilot loop works:</strong> creator-side provenance and authorship tools. This may scale further, but it needs simpler onboarding, consumer-grade billing, evidence storage, and marketplace/export integrations that are not yet core to the current app.</p>\n<p><strong>Initial paid offer:</strong> &quot;Managed Linked Art Launch Pilot&quot; — fixed-scope onboarding of one collection export into a hosted workspace, including data-quality report, Linked Art API, public browse pages, provenance/rights review flags, and a monthly evidence packet. Manual invoicing is acceptable for the first 1-3 concierge pilots; `pnpm pilot:packaging` now makes that support limit executable and blocks repeatable SaaS until subscription checkout, webhook entitlement sync, customer billing portal, and plan-change audit evidence exist.</p>\n<h3 id=\"saas-roadmap-track\">SaaS Roadmap Track</h3>\n<p>| Phase | Goal | Build / decide | Exit criteria |</p>\n<p>|---|---|---|---|</p>\n<p>| SaaS-0: Positioning + offer | Turn the technical platform into a sellable pilot. | ✅ `/pilot` now publishes the ICP, pilot promise, pricing hypothesis, deliverables, data prerequisites, support boundaries, success metrics, commercial-readiness ledger (`0` paid pilots, manual invoice path, in-app billing deferred), ten qualified prospect profiles, and a 13-account outreach queue with structured stages, status evidence, derived counts, three non-US prospects, and one recorded Te Papa web-form outreach. | Offer page is published, success metrics are explicit, named accounts are listed, and status tracking is visible; full exit now needs a reply or disqualification plus invoice-backed pilot proof. |</p>\n<p>| SaaS-1: Concierge paid pilot | Earn first non-demo revenue without overbuilding self-serve. | ✅ `docs/ops/managed-linked-art-pilot-runbook.md` now defines the pilot workspace setup runbook, tenant namespace convention, manual plan entitlement config, activation events, support intake process, customer evidence packet template, and `pnpm pilot:packaging` supportability check. Next: follow up only if Te Papa replies or the follow-up date arrives, then execute one invoice-backed pilot dataset with completed real-tenant activation milestones. | 1-3 invoice-backed paid pilots onboarded; each reaches first value within 7 days; pilot users can view/import/query/export without engineer intervention for routine tasks; packaging check remains supportable. |</p>\n<p>| SaaS-2: Multi-tenant product core | Make the app safe for multiple paying organizations. | ✅ Service-layer org-scoped storage isolation is in place for records, jobs, persisted AgentTask artifacts, researcher annotations, audit logs and org audit exports, ActivityStreams feed reads, activity readiness metrics, Postgres storage export, DR restore rehearsal, scoped public browse/derived reads, scoped AI/editorial read dependencies, wiki draft storage/access routes, wiki sync-map/reverse-ETL artifacts, authenticated org-session preview fallback for workspace pages, first-class managed `org-tenants.json` org/membership/invite backing, admin/team invite APIs, the `/orgs` operator UI, membership-validated `/api/orgs/active` cookie selection, workspace active-org status/selector/switch affordance plus stale-selection feedback, selected-org propagation through shared preview/storage/gate resolvers, records, wiki draft, annotation, AgentTask, and scoped AI/editorial route tenant RBAC read/write evidence, representative records/annotation/wiki draft/scoped AI-editorial non-member route RBAC evidence, non-admin org administration denial evidence, org-bound pilot entitlement/counter gates, and stable pilot API rate-limit denials, with Auth.js resolving active org memberships before compatibility env mappings. Support impersonation policy is now defined and test-locked in the procurement packet; next support-access evidence is route-level implementation proof only if the feature ships. | Tests prove tenant isolation at service and route boundaries; launch review includes tenant security checks; one hosted deployment supports multiple orgs without data bleed. |</p>\n<p>| SaaS-3: Billing + growth loop | Move from manual pilots to repeatable subscriptions. | ✅ Interim plan gates and durable manual pilot entitlement validation are executable in `src/services/pilot-entitlements.ts` and stored in managed `storage/pilot-entitlements.json`; `src/services/pilot-saas-packaging.ts` now decides when manual invoice billing is still enough and when subscription billing is required. Next: add pricing page, checkout or invoice-backed subscriptions, billing webhooks, usage enforcement, metered usage, trial/activation emails, onboarding checklist UI, churn/cancel reasons, and product analytics dashboard. | New org can sign up or be provisioned in under 15 minutes; MRR, activation, retention, support tickets, and usage are visible weekly; `pnpm pilot:packaging -- --target=repeatable-saas --check` passes. |</p>\n<p>| SaaS-4: Reliability + compliance for institutions | Make paid deployments procurement-friendly. | ✅ First procurement readiness packet is landed with security overview, data-flow diagram, hosting/subprocessor assumptions, backup/restore proof path, incident response summary, and checklist. Next: add customer-facing status page, SLA/SLO reporting, DPA/legal packet, access-review reports, deployment-specific backup evidence exports, incident drill evidence, and data-retention controls. | Controlled beta evidence is green enough for pilots; `pnpm review:goals:check` must be green before broad public SaaS claims. |</p>\n<p>| SaaS-5: Profitability gate | Prove the business model, not just the software. | Track gross-margin percentage, cloud cost per tenant, support minutes per account, onboarding cost, conversion rate, retention, expansion, and CAC/payback by channel. | Positive gross-margin per tenant, repeatable acquisition channel, retention evidence, and at least one pricing tier that remains profitable after support + infra cost. |</p>\n<h3 id=\"saas-product-backlog\">SaaS Product Backlog</h3>\n<p>| Capability | Current state | SaaS-grade next step |</p>\n<p>|---|---|---|</p>\n<p>| Tenant/account model | Auth roles and Postgres storage exist; pilot entitlement/counter tests prove exact-tenant and org-bound gate isolation; `src/services/org-tenants.ts` stores first-class orgs, active/inactive memberships, and hashed-token invites in managed storage; `src/services/active-org-selection.ts` validates and persists selected active orgs for signed-in members and now shares that membership-validated resolver with request storage, preview, and route-gate scope; `src/services/org-session-status.ts` resolves sanitized active-org display state and generic stale-selection warnings; admin-only org APIs create/list orgs, memberships, sanitized invites, revocations, public invite acceptance, form posts, and org-scoped audit rows; `/orgs` provides the current operator UI for org creation, membership adds, invite creation, sanitized invite review, and pending-invite revocation; the workspace shell shows active org status, storage scope, membership role, accessible-org count, selector, stale-selection warning, and a switch/manage affordance without token material; Auth.js resolves active memberships into session org ids before compatibility env mappings; records, jobs, and persisted AgentTask artifacts support org-scoped service-layer storage under a shared root; tenant-tagged records, jobs, AgentTask, annotation, activity, audit, import, public browse/derived read routes, AI/editorial read routes, wiki draft access routes, wiki sync-map/reverse-ETL routes, and preview pages now propagate exact tenant or authenticated org scope into backing stores or read models. | Add route-level support-access implementation safeguards only if support-as-customer ships, plus broader tenant RBAC evidence before self-serve hosting. |</p>\n<p>| Plans and entitlements | `src/services/pilot-entitlements.ts` defines `free`, `pilot`, `institution`, and `enterprise` plan gates for imports, AI calls, storage, users, exports, API rate limits, and feature access; it also validates and persists interim manual pilot entitlement records by exact `tenantId` with optional `orgId` binding in managed `storage/pilot-entitlements.json`, evaluates requested usage against the active plan, and `src/services/pilot-route-gates.ts` reads tenant or selected authenticated-org usage from managed `storage/pilot-usage-counters.json` before provider facade import/search/profile, AI, content generation, records API, and records export work runs, returns stable `429`/`Retry-After` responses for API-per-minute overages, then records successful 2xx work back into the same counter ledger under the selected scope. `src/services/org-tenants.ts` now gives plan gates a first-class org/membership/invite backing store, `src/services/active-org-selection.ts` persists membership-validated org choice and feeds shared selected-org resolution into route gates, `src/services/org-session-status.ts` makes active-org scope visible in the workspace shell, while `proxy.ts` blocks tenant-tagged direct legacy provider routes, `src/auth/roles.ts` derives provider import write gates from the capability registry, scoped service storage covers records/jobs/AgentTask artifacts, records/jobs/AgentTask routes pass tenant identity into scoped stores, browse plus AI/editorial read APIs select scoped record stores when request context is scoped, wiki draft access routes select scoped draft stores, wiki sync-map/reverse-ETL routes select scoped stores, and preview pages select authenticated org records when query tenant scope is absent. | Add richer plan surfaces, production limiter metadata, and usage dashboards before supporting self-serve multi-org hosting. |</p>\n<p>| Billing | No in-app billing; `/pilot` now visibly says `0` paid pilots, manual invoice entitlement only, and in-app billing not built. First pilots have a durable manual invoice-backed entitlement contract with required invoice reference, namespace, owner, publication boundary, monthly evidence cadence, and Postgres export coverage, plus `pnpm pilot:buyer-pack` for generating the buyer-specific capture checklist and timestamped run artifact before packet creation; `/readiness` now surfaces that buyer handoff as its own waiting source until real buyer fields and invoice evidence arrive. | Use manual invoice entitlement records for pilots; graduate to Stripe or equivalent checkout/webhooks only after signed pilot pricing and activation evidence are validated. |</p>\n<p>| Onboarding | Developer-led setup works; the managed pilot runbook now defines concierge workspace setup, source-data requirements, namespace rules, and a seven-day activation checklist, but self-serve setup does not exist. | Execute the runbook on one real dataset, then add guided org setup, sample dataset path, first-value dashboard, and onboarding email flow. |</p>\n<p>| Usage analytics | Launch/exit evidence exists; GA4 page analytics is wired from the root layout when `NEXT_PUBLIC_GA_MEASUREMENT_ID` is set, with the current web stream ID `G-WPGJX5H0S7` documented for Vercel. The site now ships a browser-persisted analytics consent banner and privacy-choices control; Consent Mode v2 defaults deny ad storage, ad user data, ad personalization, and analytics storage until an analytics choice exists, advertising consent remains denied even when analytics is accepted, and `pnpm privacy:consent:check` writes `artifacts/privacy/analytics-consent-latest.json` proving GA4 ID validation, denied-by-default Consent Mode v2, persisted banner controls, `/privacy` disclosure, root-layout tag wiring, and the no-ad-personalization expansion guard. `src/services/pilot-outreach-events.ts`, `src/services/pilot-activation-events.ts`, `src/services/pilot-support-issues.ts`, `src/services/pilot-kpi-events.ts`, and `src/services/pilot-evidence-packet.ts` now record, summarize, and package required outreach/activation/support/KPI evidence, `pnpm pilot:outreach`, `pnpm pilot:activation`, `pnpm pilot:support`, `pnpm pilot:kpi`, and `pnpm pilot:evidence --markdown` give operators validated write/export paths for real JSON and customer-readable Markdown evidence, `/pilot` renders honest zero-sent and zero-complete ledgers until real records exist, and route-level entitlement gates read exact-tenant month/minute counters from managed storage and record successful gated route work, but broader tenant-aware activation analytics remain thin. | Implement tenant-aware tracking for activation milestones, validation improvements, customer views, weekly active users, usage cost, monthly evidence exports, and legal/CMP review before enabling ads, remarketing, or region-specific marketing workflows. |</p>\n<p>| Support operations | Technical docs are strong; the managed pilot runbook now defines support intake fields, severity levels, response rules, and evidence cadence for concierge pilots. | Formalize intake tooling, known-issues page, escalation policy, and pilot feedback cadence once the first pilot is active. |</p>\n<p>| Sales/marketing surface | `/pilot` now publishes the buyer-facing Managed Linked Art Launch Pilot page with problem, buyer, offer, pricing hypothesis, success metrics, support boundaries, source-network CTA, contact CTA, shared primary/footer nav access, named outreach queue, an outreach status ledger with non-clipped status cells, and a zero-complete activation evidence ledger backed by managed outreach/activation events plus operator commands needed to record and package real evidence. | Send/record the first real outreach, then add proof screenshots, completed activation milestones, and a customer evidence packet once the first pilot is active. |</p>\n<p>| Procurement readiness | `docs/ops/procurement-readiness-packet.md` now packages a buyer-reviewable security overview, Mermaid data-flow diagram, hosting/subprocessor assumptions, backup/restore evidence path, incident response summary, checklist, and explicit non-SOC-2 / incomplete-tenant-isolation limits. | Attach actual deployment-specific evidence, legal/DPA artifacts, access-review exports, incident drill evidence, and customer-specific subprocessors once the first pilot is active. |</p>\n<h3 id=\"current-evidence-blockers\">Current Evidence Blockers</h3>\n<p>| Era C exit check | Current evidence | Required to clear |</p>\n<p>|---|---|---|</p>\n<p>| SOTA §20.4 p95 SLOs | The current strict handoff reports `20/30` retained deployed SLO samples across `7/30` distinct UTC days, with `13/30` passing samples across `6/30` passing days and `7` failed/incomplete retained rows. `pnpm longterm:evidence:public` now reports SLO trend intake (`23` raw timestamped rows, `20` inside the report window, `3` older) plus distinct UTC observation days and acceptance rows so stale, clustered, old, or failed retained samples cannot masquerade as 30-day evidence. | Keep complete five-scenario `pnpm k6:slo` samples passing against the deployed target, then retain 30 days of passing samples; keep all p95s under policy thresholds until the SLO depth and failure-free acceptance rows are ready. |</p>\n<p>| Public-read uptime | Live public-read URL is known (`https://www.metamuseum.org`) and deployment preflight probes `/`, `/api/health`, and `/api/records` for launch-critical read availability; retained public-read uptime now has `117` probe snapshots across `9/30` observed UTC days, but availability is only `0.9744`, still below the 99.9% threshold because one retained failed sample remains. `pnpm monitoring:telemetry:public` forces a public probe snapshot, and `pnpm longterm:evidence:public` turns the uptime snapshot/history into both accumulation runway and maintenance repair artifacts with uptime depth, availability, and failed-sample age-out acceptance rows. | Keep scheduled public probes running via `METAMUSEUM_PUBLIC_READ_BASE_URL=https://www.metamuseum.org` / uptime envs; retain a clean 30-day window with &gt;= 99.9% availability until the uptime observation-depth and availability rows are ready. |</p>\n<p>| Activity feed adoption | `3/3` declared external consumers in the latest local syndication artifact, with `metahistorybook-harvester-prod`, `daily-metahistorybook-prod`, and `wikidataexplorer-metamuseum-prod` filed from production reads; the restored `storage/activity-subscriptions.json` ledger now reports `3/3` matched durable external callbacks and `3` accepted callback rows. Single-consumer and three-consumer matrix proof tooling are available, `pnpm activity:partner-pack` writes the partner-specific `limit=100` read/subscription handoff plus per-consumer acceptance rows and a timestamped run artifact, now including the optional `type=Update -&gt; linkedArt.id -&gt; /api/events/...` dereference check; `/readiness` surfaces both broad community outreach and the waiting partner handoff as generated sources, and the no-ID pack includes three `pending-consumer-id` outreach slots while keeping `consumerIds: []` so placeholders cannot satisfy strict proof. `pnpm activity:community-outreach` captures broad Linked Art/Slack asks as outreach context with `strictEvidence: false`, prints the latest JSON, Markdown, and timestamped run artifact paths for attachment, and `/readiness` shows when its channel, message reference, timestamp, or owner still need to be captured. `/api/activity`, `/api/activity/collection`, and `/api/activity/page/{page}` record each declared consumer&#39;s observed `Create`/`Update`/`Delete` feed activity types, embedded `linkedArt.id` values now dereference through `/api/events/{encodedSourceActivityId}` with `_complete: false` plus source-preserving `equivalent[]`, `/api/records/{id}` now emits activity autodiscovery `Link` headers, `/api/providers/capabilities` advertises activity endpoint templates/filter/signing metadata, callback subscriptions can declare HMAC-SHA256 signing via secret references, `pnpm activity:adoption:matrix` plus the long-term runway/maintenance reports expose observed/missing type coverage, `pnpm activity:subscription:verify` records recent 2xx callback proof without hand-editing `storage/activity-subscriptions.json`, `pnpm activity:syndication:evidence` reports durable callback row counts, and `pnpm longterm:evidence:public` ignores placeholder-looking declared IDs in the long-term adoption runway. The first reviewed `Update` row is now live and partner-confirmed in production from a real Met object `437133` metadata delta; MetaHistoryBook also confirmed on `2026-07-10T00:18:38Z` that `/evidence`, `/api/evidence`, `/api/evidence/ledger`, and the Update row&#39;s hosted `/api/events/...` Linked Art dereference are externally live and conformant. `pnpm providers:coverage:seed` now verifies all `14/14` source-provider lanes before the tombstone scan, `pnpm activity:tombstone:scan` keeps the upstream tombstone watch fresh with provider-aware support/skipped/duplicate reporting, and `pnpm moma:dataset:diff` now provides a separate MoMA open-data snapshot comparison lane whose removals stay review-required and never satisfy ActivityStreams `Delete`. The latest run considered `126` stored records at `2026-07-10T01:07:06.186Z`, scanned `68` unique upstream targets across all `14` source providers, and found `0` upstream `404`/`410` tombstones. | Collect a real upstream `404`/`410` tombstone before emitting `Delete`, then send the second deploy-note for MetaHistoryBook to re-read `type=Delete`; keep all three callback verification rows fresh with `pnpm activity:subscription:verify`, publish retry/delivery guarantee windows, and capture refreshed `pnpm activity:adoption:matrix`, `pnpm providers:coverage:seed`, `pnpm activity:tombstone:scan`, `pnpm moma:dataset:diff` when a new MoMA snapshot is available, plus `pnpm activity:syndication:evidence` artifacts. |</p>\n<p>| SOTA §26 KPIs | Failing `reconciliationAutoApproveRate` and `reconciliationPrecisionReviewed`; local record-enrichment preview now passes after counting unique recognized authority references (`52/57`, `0.9123` against the `0.8` target), but it still must be regenerated from a production/postgres/warehouse records export before strict proof. AI query cost telemetry is sourced and within policy in the latest artifact. `pnpm monitoring:kpi-evidence` now creates the `monitoring/kpi-evidence.json` input from record-enrichment and reconciliation distribution counts, while `pnpm monitoring:kpi-evidence:production` requires Postgres storage, reviewed precision requires real reviewed/accepted auto-link counts plus a named production review source, acceptance rows distinguish production-shaped KPI inputs from local/current-environment exports, `diagnostics.blockers[]` names the exact observed value, Era C target, next evidence, command, and artifact for each KPI gap, `diagnostics.evidenceNeeds.enrichment.sampleRecordGaps[]` lists a capped repair sample of under-enriched record IDs plus existing recognized authority URIs and suggested Linked Art fields, `diagnostics.evidenceNeeds.reconciliation` now includes the raw candidate distribution plus a production `sourceReady` flag, `diagnostics.evidenceNeeds.reviewedPrecision` now includes a named-source readiness flag and source requirement, `diagnostics.capturePlan.rows[]` gives the production field/source checklist for enrichment, reconciliation distribution, reviewed precision, and strict refresh, and `diagnostics.handoffSummary` now reports both source-shape next evidence and `nextMetricCommand`/`nextMetricEvidenceNeeded` for the first KPI threshold blocker. `/readiness` and the `pnpm monitoring:kpi-evidence` console summary now lift the first repair target, suggested field, production source labels, raw candidate counts, and reviewed-source readiness so operators can triage the gap without opening raw JSON. | Export real production record-enrichment + reconciliation review counts to `monitoring/kpi-evidence.json`, make every KPI acceptance and capture row ready, clear `diagnostics.blockers[]`, confirm `diagnostics.handoffSummary.status` is `ready-to-refresh`, then rerun telemetry sync and Era C gates. |</p>\n<h3 id=\"next-operating-plan\">Next Operating Plan</h3>\n<ol><li><strong>Deployment foundation</strong> — ✅ preflight automation and runbook are landed (`pnpm launch:preflight`, `pnpm launch:preflight:production`, `docs/ops/deployment-preflight.md`); Neon-backed `DATABASE_URL` is seeded with all present managed storage documents, `DATABASE_URL` now verifies with `sslmode=verify-full`, `pnpm launch:smoke-token` now generates/rotates the staging researcher smoke token in `.env` without printing it, and the Next.js app is live at `https://www.metamuseum.org` on Vercel against Neon (`vercel.json`, `render.yaml`, `docs/deployment.md` landed; the close-out guard self-skips on Vercel). <strong>Update 2026-07-03:</strong> the rotated production `DATABASE_URL` is active, `/api/records` returns `200`, production preflight records no effective `METAMUSEUM_TEST_ROLE_OVERRIDE_TOKEN`, public base/SLO/IIIF metadata are set, validation and reconciliation Render `/health` probes pass, the active deployment is newer than the recorded secret rotation, and `pnpm launch:preflight:production` passes `20/20`. The full launch-evidence packet has been refreshed; strict readiness now waits on Era C real-world proof, not stale preflight data.</li></ol>\n<ol><li><strong>Evidence pipeline</strong> — ✅ nightly workflow now prefers deployed-target `pnpm k6:slo`, seeds `/api/ai/query` telemetry, probes declared activity adoption, captures the public evidence-ledger live-probe packet, preserves local `pnpm k6:slo:ci` fallback, runs `pnpm longterm:evidence`, commits compact rolling k6/uptime/adoption/evidence-ledger inputs back to `main`, and uploads performance/activity/monitoring plus long-term runway artifacts; public-read uptime probe evidence is active but still needs 30 clean observation days.</li></ol>\n<ol><li><strong>Telemetry completeness</strong> — ✅ AI query runs emit per-query usage/cost logs, and `pnpm monitoring:kpi-evidence:production` can now generate `monitoring/kpi-evidence.json` with aggregate production record-enrichment + reconciliation counts only when Postgres storage is active; still generate the real production export before the next exit-gate run.</li></ol>\n<ol><li><strong>External adoption proof</strong> — ✅ partner/bot proof commands and runbook are landed (`pnpm activity:adoption:probe`, `pnpm activity:adoption:matrix`, `pnpm activity:community-outreach`, `pnpm activity:syndication:evidence`, `docs/ops/activity-adoption-proof.md`); the community outreach command records broad asks without turning them into strict proof, `/readiness` surfaces those rows as outreach context, and the syndication evidence command initializes an empty subscription ledger and reports durable callback rows without treating missing rows as proof. July 8 verification passed the provider tombstone-watch and local review-goals refresh, with strict ActivityStreams proof now blocked only on live `Delete` read coverage after real partner-confirmed `Update` and restored `3/3` durable callback rows. Keep validating `class: &quot;declared&quot;`, `declaredId`, `isExternal`, and recent `lastSeenAt` in `storage/activity-consumers.json`, then keep callback verification rows fresh for each counted consumer.</li></ol>\n<ol><li><strong>Launch review</strong> — ✅ `pnpm launch:review` / `pnpm launch:review:production` aggregate latest preflight, exit-gate, security, DR, public-trust, a11y, and explore-smoke evidence into a packet, and `pnpm launch:beta:readiness` now summarizes controlled-beta go/no-go status from launch-review plus deployment-preflight artifacts. <strong>Update 2026-07-04:</strong> production is live on Vercel + Neon at `https://www.metamuseum.org`, the rotated production `DATABASE_URL` is active, `/api/records` returns `200`, `pnpm launch:preflight:production` passes `20/20` with explicit non-secret rotation metadata, full `pnpm launch:evidence:production` passes `8/9`, and `pnpm launch:review:production` passes `7/8`. Current launch status is governed by `pnpm review:goals:check`, which still reports external evidence required until Era C, long-term SLO/uptime, ActivityStreams, KPI, and pilot real-world blockers are green.</li></ol>\n<ol><li><strong>SaaS packaging</strong> — ⚠️ `/pilot` is shared-nav reachable and publishes the Managed Linked Art Launch Pilot offer for concierge paid pilots, including pricing hypothesis, scope, prerequisites, support boundaries, success metrics, a commercial-readiness ledger that honestly shows 0 paid pilots, manual invoice entitlements, and in-app billing not built. The named outreach ledger now has 13 researched accounts, 1 sent message, and 0 replies: Te Papa web-form outreach was recorded at `2026-07-04T18:30:00.000Z` from the user&#39;s reported July 4, 2026 11:30 AM Pacific submission, while Museums Victoria and Art Gallery of Ontario remain researched prospects. `pnpm pilot:buyer-pack -- --submission-mode=form --omit-pricing` creates form-safe no-pricing outreach and a reply-ready packet with data checklist, seven-day timeline, sample outputs, and privacy/security notes, but the latest Te Papa pack still blocks until a real invoice reference exists. `pnpm pilot:outreach`, `pnpm pilot:activation`, `pnpm pilot:support`, `pnpm pilot:kpi`, and `pnpm pilot:evidence --markdown` convert real manual outreach, activation, support, KPI, entitlement, usage, retention, and gross-margin ledgers into explicit `blocked` or `ready` JSON plus Markdown packets while rejecting chronology errors, placeholder billing/KPI references, unsupported replies, and incomplete support states. The next SaaS evidence target is a Te Papa reply/follow-up or disqualification, then a signed invoice-referenced pilot and real tenant dataset with dated activation, support, KPI, retention, and gross-margin evidence; do not claim profitable SaaS readiness until recurring revenue, support load, retention, and gross-margin evidence are real.</li></ol>\n<ol><li><strong>Documentation currency</strong> — ✅ every iteration must update `README.md` and `docs/roadmap.md` before `pnpm session:closeout`; `scripts/session-closeout.ts` enforces this on the normal closeout path by comparing both files to the previous closeout timestamp. Latest CI hardening keeps workflow JavaScript Actions on Node 24-native major versions while preserving the project’s Node 20 app execution path; latest UI polish keeps the home hero carousel in this current surface because clear full-color artwork imagery, attribution, reuse context, and a centered non-overlapping info panel are part of the public Linked Art trust contract.</li></ol>\n<ol><li><strong>Agent productionization</strong> — ✅ persistent AgentTask review history is landed (`agent-tasks.json` managed storage + `/api/agents/tasks`), the internal AG2 bridge boundary is wired for Mercator/Janus behind `METAMUSEUM_AG2_BRIDGE_ENABLED`, and the local Python AG2 worker endpoint is available at `services/ag2-worker` with review-only contract tests, route-to-worker trace propagation, timeout/refusal fallback coverage, safe enablement docs, and live-worker eval artifacts via `pnpm ag2:worker:eval`. ⚠️ next value is collecting operator sign-off for any production bridge enablement; A2A/AG-UI remain deferred.</li></ol>\n<p>---</p>\n<h2 id=\"linked-art-adherence-uplift-current-high\">Linked Art adherence uplift (current -&gt; high)</h2>\n<p>This section turns the current medium/medium-high areas into explicit completion criteria.</p>\n<h3 id=\"a-validation-architecture-depth-b2-follow-through\">A. Validation architecture depth (B2 follow-through)</h3>\n<p>Current: validation architecture is in place and standards-linked.  </p>\n<p>Target: high adherence through continuous standards-backed enforcement.</p>\n<p>Adherence upgrade target:</p>\n<ul><li>[x] ✅ Validation depth moved from &quot;in place&quot; to continuous fixture-backed drift enforcement.</li></ul>\n<p>Status:</p>\n<ul><li>[x] ✅ Complete.</li><li>[x] ✅ Evidence: `/explore` includes `vanda` source toggle and `/artwork/[id]` now exposes digital/IIIF manifest-image links when present in imported records.</li><li>[x] ✅ Provider/import transform policy is now executable via fixture manifest + tests:</li><li>`tests/fixtures/validation/provider-fixture-manifest.json`</li><li>`tests/quality/validation-architecture-depth.test.ts`</li><li>[x] ✅ Scheduled revalidation pass landed:</li><li>`.github/workflows/validation-drift.yml` (weekly + manual dispatch)</li><li>`scripts/validation-drift.ts`</li><li>[x] ✅ CI drift visibility + regression blocking landed:</li><li>`.github/workflows/ci.yml` runs `pnpm validation:drift:check`</li><li>net-new critical violations fail the job</li></ul>\n<p>Definition of done:</p>\n<ul><li>[x] ✅ Validation coverage includes object, digital, provenance, shared structures, and endpoint-shape fixtures from the reference rounds used in active slices.</li><li>[x] ✅ CI shows stable/no-regression validation trend for two consecutive release cycles.</li><li>`config/validation-drift-cycles.json` tracks release-cycle snapshots.</li><li>`pnpm validation:drift:trend` performs executable two-cycle no-regression gating.</li></ul>\n<h3 id=\"b-provider-rollout-completeness-b5\">B. Provider rollout completeness (B5)</h3>\n<p>Current: all planned expansion providers are landed.  </p>\n<p>Target: high adherence with repeatable, standards-mapped provider slices.</p>\n<p>Adherence upgrade target:</p>\n<ul><li>[x] ✅ Provider rollout discipline is locked to keep all landed B5 providers green with standards-mapped tests (fixtures + protocol/profile checks + parity checklist).</li></ul>\n<ul><li>[x] ✅ Execute remaining providers as independent slices (Louvre, Harvard, Smithsonian, V&amp;A, Princeton, Europeana, AIC, CMA), each with:</li><li>[x] ✅ adapter isolation conformance</li><li>[x] ✅ fixture-anchored standards mapping</li><li>[x] ✅ protocol/profile checks from B8</li><li>[x] ✅ Track per-provider readiness in this roadmap with explicit `not started / in progress / done` status and standards round coverage.</li></ul>\n<p>Provider readiness matrix:</p>\n<p>| Provider | Status | Standards round coverage | B8 protocol/profile checks | Notes |</p>\n<p>|---|---|---|---|---|</p>\n<p>| Rijks | done | object + digital + provenance + shared structures + endpoint-shape fixture anchors mapped to `LinkedArtModel1.0-Reference.md` | complete | Routes + adapter + tests are landed and included in provider protocol conformance suite. |</p>\n<p>| NGA | done | object + digital + provenance + shared structures + endpoint-shape fixture anchors mapped to `LinkedArtModel1.0-Reference.md` | complete | CSV ingest/provider slice landed with adapter + profile/search/import routes + tests. |</p>\n<p>| Louvre | done | object + shared structures + references fixture anchors mapped to `LinkedArtModel1.0-Reference.md` | complete | Routes + adapter + tests landed with provider facade wiring. |</p>\n<p>| Harvard | done | object + shared structures + endpoint-shape fixture anchors mapped to `LinkedArtModel1.0-Reference.md` | complete | Routes + adapter + tests landed with provider facade wiring. |</p>\n<p>| Smithsonian | done | object + shared structures + data-discovery fixture anchors mapped to `LinkedArtModel1.0-Reference.md` | complete | Routes + adapter + tests landed with provider facade wiring. |</p>\n<p>| V&amp;A | done | object + digital + data-discovery fixture anchors mapped to `LinkedArtModel1.0-Reference.md` | complete | Routes + adapter + tests landed with provider facade wiring. |</p>\n<p>| Princeton | done | object + digital + shared structures fixture anchors mapped to `LinkedArtModel1.0-Reference.md` | complete | Routes + adapter + tests landed with provider facade wiring. |</p>\n<p>| Europeana | done | object + shared structures + data-discovery fixture anchors mapped to `LinkedArtModel1.0-Reference.md` | complete | Routes + adapter + tests landed with provider facade wiring. |</p>\n<p>| AIC | done | object + digital + shared structures fixture anchors mapped to `LinkedArtModel1.0-Reference.md` | complete | Routes + adapter + tests landed with provider facade wiring. |</p>\n<p>| CMA | done | object + digital + shared structures fixture anchors mapped to `LinkedArtModel1.0-Reference.md` | complete | Routes + adapter + tests landed with provider facade wiring. |</p>\n<p>Provider parity checklist (all must be complete per provider before status can be set to `done`):</p>\n<ul><li>[x] ✅ identity mapping (stable URI + `equivalent` handling)</li><li>[x] ✅ activity/event modeling preserved (no object-person shortcut regressions)</li><li>[x] ✅ rights/reuse + attribution semantics preserved and surfaced</li><li>[x] ✅ IIIF/link-layer handling preserved when source provides it</li><li>[x] ✅ source provenance metadata preserved end-to-end (`_source.provider`, source URL, ingest time)</li></ul>\n<p>Definition of done:</p>\n<p>      kept ignored from the main app repository except for the tracked pointer README; both are documented as</p>\n<p>      snapshot/open-data provider candidates rather than live public API or tombstone sources.</p>\n<p>      maps `ObjectID` to `https://www.moma.org/collection/works/{ObjectID}`, maps artists by `ConstituentID` with</p>\n<p>      Wikidata/ULAN `equivalent[]`, preserves `Cataloged` quality status and conservative image policy in `_source`,</p>\n<p>      exposes `/api/moma/<em>` plus `/api/providers/moma/</em>`, and is explicitly excluded from live `404`/`410`</p>\n<p>      tombstone scans pending a separate dataset-diff deletion workflow. Provider note: providers/moma-open-data.md(providers/moma-open-data.md).</p>\n<ul><li>[x] ✅ All planned B5 providers shipped with route + adapter + tests + standards mapping notes.</li><li>[x] ✅ Provider parity checklist complete for identity, activity modeling, rights, IIIF, and source provenance.</li><li>[x] ✅ Local upstream metadata mirrors are organized under `data/source-repos/` with `moma-collection` and `tate-collection`</li><li>[x] ✅ MoMA is now wired as a snapshot/open-data provider: `src/adapters/moma-open-data.ts` reads local JSON/CSV,</li></ul>\n<h3 id=\"c-hal-search-relations-conformance-rounds-71-79\">C. HAL + Search relations conformance (rounds 71-79)</h3>\n<p>Current: documented in the standards reference, partially deferred in platform slices.  </p>\n<p>Target: high adherence with enforceable API behavior.</p>\n<ul><li>[x] ✅ Add conformance tests for OrderedCollection/OrderedCollectionPage search response shapes.</li><li>[x] ✅ Enforce stable relation naming and discoverability contracts via search relation fields (`nextPage` / `prevPage`) and HAL-aware protocol assertions.</li><li>[x] ✅ Prevent inverse-relationship duplication drift by asserting search-driven inverse discovery patterns.</li></ul>\n<p>Definition of done:</p>\n<ul><li>[x] ✅ Representative search endpoints pass relation + pagination + shape conformance tests.</li><li>[x] ✅ HAL link contract tests pass for versioning, related search links, and format/profile discoverability.</li></ul>\n<p>Status:</p>\n<ul><li>[x] ✅ `tests/quality/hal-search-relations-conformance.test.ts` enforces response-shape + relation-contract behavior on representative direct and provider-facade search routes.</li><li>[x] ✅ `tests/quality/protocol-conformance.test.ts` continues to enforce HAL separation + media-type/profile behavior on public API payloads.</li></ul>\n<h3 id=\"d-era-b-exit-gate-closure-readiness\">D. Era B exit-gate closure readiness</h3>\n<p>Current: Era B gate closed for the current scope.  </p>\n<p>Target: keep it closed as new providers land.</p>\n<ul><li>[x] ✅ B6 authority-cache request-path policy enforced.</li><li>[x] ✅ B8/B9 conformance suites in CI.</li><li>[x] ✅ Postgres mode is now the default storage-of-record when `DATABASE_URL` is present.</li><li>[x] ✅ `storage/*.json` removed from version control.</li><li>[x] ✅ Write audit-log verification in CI for all primary write routes.</li></ul>\n<p>Definition of done:</p>\n<ul><li>[x] ✅ Era B exit gate lines are green with evidence links to tests and commands (`tests/quality/era-b-exit-gate.test.ts`, `tests/quality/protocol-conformance.test.ts`, `tests/quality/provider-protocol-conformance.test.ts`, `tests/quality/linked-art-b9-guardrails.test.ts`).</li></ul>\n<p>Adherence upgrade target:</p>\n<ul><li>[x] ✅ Era B sustainment is continuously enforced: provider-slice conformance, authority-cache policy, and write-audit checks remain green as new sources land.</li></ul>\n<p>Execution policy:</p>\n<ul><li>[x] ✅ No provider/validation PR merges without round + fixture-anchor standards mapping.</li><li>[x] ✅ No protocol-affecting merges without conformance test coverage for headers/shape/negotiation touched.</li><li>[x] ✅ Enforcement evidence:</li><li>`.github/pull_request_template.md`</li><li>`tests/quality/execution-policy-gates.test.ts`</li></ul>\n<p>---</p>\n<h2 id=\"stack-decisions-locked-in\">Stack decisions — locked in</h2>\n<p>| Layer | Decision | Locked because |</p>\n<p>|---|---|---|</p>\n<p>| Framework | Next.js 16 App Router + RSC | already scaffolded; matches SOTA §11 |</p>\n<p>| UI lang | TypeScript 5, `strict: true` | scaffolded |</p>\n<p>| Styling | <strong>Custom CSS</strong> — design tokens + BEM-lite component classes in `app/globals.css`; no utility framework | user decision (reversed earlier Tailwind choice); resolves SOTA §30 Q3 |</p>\n<p>| Forms | React Hook Form + Zod | SOTA §3.2 |</p>\n<p>| Data fetching | RSC `fetch` first; TanStack Query for interactive client state | SOTA §11.3 + Next 16 cache-components model |</p>\n<p>| Server state mutations | Server Actions over fetch-based POSTs where possible | Next 16 idiom |</p>\n<p>| Tests | `node:test` + `node:assert` via `tsx`, Playwright for e2e, axe-core for a11y | SOTA §23 + legacy convention |</p>\n<p>| Pkg manager | pnpm | scaffolded |</p>\n<p>| Persistence (this era) | Postgres JSONB is the storage-of-record behind `src/utils/storage.ts` (`postgres` default with compatibility `file`/`double-write` modes) | preserves stable call sites during/after B3 migration |</p>\n<p>| Triple store (SOTA era) | <strong>GraphDB (Ontotext)</strong> — Community Edition for OSS path; SE/EE if SPARQL p95 demands | user decision; resolves SOTA §30 Q1 |</p>\n<p>| Search index (SOTA era) | <strong>Solr 9</strong> (LUX-aligned) | architecture decision (May 30, 2026); replaces Solr/OpenSearch fork |</p>\n<p>| Persistence (SOTA era) | Postgres 16 + JSONB · Solr 9 · GraphDB · pgvector | SOTA §3.4 / §8 with finalized search choice |</p>\n<p>| Curator backend (SOTA era) | <strong>In-house curator console</strong> (custom, Linked Art-native) | architecture decision (May 30, 2026); draws lessons from Arches/Ogee without adopting platform lock-in |</p>\n<p>| Developer/ops backend | <strong>In-house ops console</strong> (pipeline/debug/automation focused) | architecture decision (May 30, 2026); complements curator console |</p>\n<p>| Canonical ID scheme | <strong>`https://lod.metamuseum.org/{type}/{ulid}`</strong> | architecture decision (May 30, 2026); opaque, sortable, federation-ready |</p>\n<p>| Publication bridge (SOTA era) | <strong>MediaWiki + custom Wikibase</strong> for Meta Wiki Art publishing | aligns Linked Art/SPARQL/citation goals; see `docs/meta-wiki-art-bridge.md` |</p>\n<p><strong>Previously deferred architecture decisions (now finalized, May 30, 2026):</strong></p>\n<ul><li>[x] ✅ Search engine: <strong>Solr 9</strong> (LUX-aligned).</li><li>[x] ✅ Curator backend: <strong>in-house custom curator console</strong>.</li><li>[x] ✅ Developer backend: <strong>in-house ops console</strong>.</li><li>[x] ✅ Canonical ID scheme: <strong>`https://lod.metamuseum.org/{type}/{ulid}`</strong>.</li></ul>\n<p>---</p>\n<h2 id=\"era-delivery-history\">Era delivery history</h2>\n<p>All three delivery eras are complete (see Status above):</p>\n<ul><li><strong>Era A — The Lift</strong> (10 PR-sized slices): TDD foundations, Met + Getty verticals, records/artworks/entities, Linked Art inspector, patterns/graph, issues/SSE, agents/jobs/content, workspace chrome.</li><li><strong>Era B — Hardening</strong> (B1–B10): Zod contracts + schema versioning, formal validation, Postgres, auth + roles, 14-provider expansion, authority caching, exhibition/literature reconciliation, protocol + modeling guardrails, ARK conformance, gateway readiness.</li><li><strong>Era C — SOTA</strong> (C1–C5): multi-modal storage + HAL, ETL + reconciliation + mapper, IIIF + visualizations, the AI layer, syndication + Meta Wiki Art + security/privacy hardening.</li></ul>\n<p>The full slice-by-slice and B-/C-series implementation detail is archived in <strong>progress/era-history.md(progress/era-history.md)</strong>. The active forward plan is <strong>roadmap-to-10.md(roadmap-to-10.md)</strong>.</p>\n<p>---</p>\n<h2 id=\"cross-cutting-standards-apply-from-slice-1-onward\">Cross-cutting standards (apply from Slice 1 onward)</h2>\n<p>These are not phases — they are continuous quality gates. Borrowed from `_legacy/AGENTS.md` and SOTA §23.</p>\n<ul><li>[x] ✅ <strong>AIDD + TDD is the default.</strong> Define behavior in natural language and map standards rounds/fixture anchors first, then write the failing test (red), pass with minimum code (green), and refactor with the suite green. Tests are the spec; reviewers read tests before reading implementation. A failing test stops the line. See CLAUDE.md(../CLAUDE.md) §&quot;We lead with AIDD + TDD&quot;.</li><li>[x] ✅ <strong>Adapters do not import each other.</strong> Bridge via `src/utils/artwork-builder.ts`.</li><li>[x] ✅ <strong>Contracts are leaf modules.</strong> No upstream deps.</li><li>[x] ✅ <strong>`_source.raw` is immutable.</strong> Transform at read time.</li><li>[x] ✅ <strong>Rights-aware by default.</strong> Every UI surface showing an image carries reuse status + attribution.</li><li>[x] ✅ <strong>Linked Art JSON-LD is the canonical data layer.</strong> UI DTOs (`Artwork`) are separate; map at the boundary.</li><li>[x] ✅ <strong>Loading / empty / error / success states</strong> on every interactive UI.</li><li>[x] ✅ <strong>Keyboard navigation + visible focus</strong> on every interactive surface.</li><li>[x] ✅ <strong>At least one test for any risky transform.</strong></li><li>[x] ✅ <strong>Cite or refuse.</strong> Generated content always carries citations + rights + review state.</li><li>[x] ✅ <strong>Next 16 specifics</strong>: `cookies()`, `headers()`, dynamic `params` are async — always `await` them.</li><li>[x] ✅ <strong>No `unknown` swallowed silently.</strong> A record with unknown rights gets an explicit &quot;Rights unknown — do not reuse&quot; badge.</li><li>[x] ✅ <strong>Reference-driven conformance.</strong> Any provider/API/schema/search/protocol PR must cite relevant linked-art/LinkedArtModel1.0-Reference.md(linked-art/LinkedArtModel1.0-Reference.md) rounds and include failing-first tests mapped to the referenced fixture anchors.</li><li>[x] ✅ <strong>Reference maintenance loop.</strong> If a PR depends on newly published Linked Art guidance not yet captured in `LinkedArtModel1.0-Reference.md`, that round/addendum must be appended before (or in the same change as) the implementation PR.</li><li>[x] ✅ <strong>Standards Mapping is required in provider/validation PRs.</strong> Include: referenced round numbers, fixture anchors exercised, and failing-first test files proving red→green conformance.</li><li>[x] ✅ <strong>PR template completion is required.</strong> Every PR must complete .github/pull_request_template.md(../.github/pull_request_template.md), including AIDD checklist gates, standards mapping, and protocol assertions touched.</li><li>[x] ✅ <strong>AI-generated tests/refactors require human semantic verification.</strong> AI can accelerate drafting, but authors/reviewers remain accountable for Linked Art correctness, provider semantics, and protocol behavior.</li><li>[x] ✅ <strong>Provider/pipeline boundary drift is actively bounded.</strong> `docs/risk-register.md` tracks risk posture and `tests/contracts/provider-boundary-contracts.test.ts` enforces adapter import boundaries.</li><li>[x] ✅ <strong>Protocol conformance is mandatory.</strong> Public API behavior must preserve JSON-LD context/profile correctness, support `GET` + `OPTIONS`, and provide baseline CORS + media-type negotiation.</li><li>[x] ✅ <strong>AI-RSI compounding loop is mandatory.</strong> Each merge requires: 72h review check, evidence capture in session log, and roadmap/README/CLAUDE updates before the next RSI expansion scope.</li><li>[x] ✅ <strong>HAL/data separation is mandatory.</strong> API navigation metadata lives in `_links` (non-semantic) and must not pollute semantic graph payloads.</li><li>[x] ✅ <strong>URI opacity is mandatory.</strong> Never infer semantics from URI path structure in router logic or client helpers.</li><li>[x] ✅ <strong>Inverse discovery via Search API.</strong> Prefer standardized search relations and OrderedCollection/OrderedCollectionPage responses rather than duplicating inverse relationship fields.</li><li>[x] ✅ <strong>Carrier/content separation is non-negotiable.</strong> `HumanMadeObject`/`DigitalObject` must remain distinct from `VisualItem`/`LinguisticObject`.</li><li>[x] ✅ <strong>Authority-backed classification UX.</strong> Curatorial/classification input paths must use controlled authority sources (AAT/ULAN/Wikidata equivalents), not free-text categories by default.</li><li>[x] ✅ <strong>Data discovery signposting.</strong> Public record HTML pages expose a single canonical `describedby` link to the Linked Art JSON-LD record.</li></ul>\n<p>Verification note (May 31, 2026):</p>\n<ul><li>The first nine cross-cutting gates above are marked complete based on current enforcement in CI/tests and live implementation patterns (provider boundary checks, contract leaf structure, `_source.raw` invariants, rights surfaces, Linked Art boundary mapping, interactive state handling, and keyboard/focus coverage).</li><li>Additional governance/protocol gates are marked complete where enforced by executable tests (`protocol-conformance`, `provider-protocol-conformance`, `hal-search-relations-conformance`, `provider-digital-content-gates`) and PR governance checks (`execution-policy-gates`, PR template standards mapping requirements).</li><li>Remaining open gates in this section are intentionally left unchecked only where future era scope is intentionally deferred; cross-cutting gate set above is now fully enforced in current Era A/B surfaces.</li></ul>\n<p>---</p>\n<h2 id=\"what-this-roadmap-deliberately-does-not-do-yet\">What this roadmap deliberately does NOT do (yet)</h2>\n<p>To stay honest about scope:</p>\n<ul><li>[x] ✅ <strong>No microservice split during Era A.</strong> All routes lived in the single Next 16 app; Python services begin in Era B (validation) and Era C (reconciliation, AI).</li><li>[x] ✅ <strong>No triple store or vector store in Era A or B.</strong> Postgres + JSONB remains sufficient until Era C search/graph patterns are activated.</li><li>[x] ✅ <strong>No module-federation for the Era A app.</strong> The app remains a single deployable Next.js build.</li><li>[x] ✅ <strong>No Arches / Ogee / Zelge adoption planned.</strong> Lessons are reused, but curator and ops surfaces remain in-house.</li><li>[x] ✅ <strong>No fancy IIIF in Era A.</strong> Current Era A/B UI uses provider image URLs; OpenSeadragon remains planned for C3.</li><li>[x] ✅ <strong>No NL→SPARQL until the SHACL gate exists</strong> (B2 → C4).</li><li>[x] ✅ <strong>No Meta Wiki Art write path</strong> until contracts, validation, auth, audit log, and Postgres cutover are stable (C5).</li></ul>\n<p>Verification note (May 31, 2026):</p>\n<ul><li>Constraints above are verified against current code/routes/dependencies and remain in force for pre-Era-C scope control.</li></ul>\n<p>---</p>\n<h2 id=\"what-i-d-build-next-concretely\">What I&#39;d build next, concretely</h2>\n<p>Era C1 prep while sustaining Era B quality gates:</p>\n<ul><li>[x] ✅ <strong>RSI-5: AI evidence drift + citation freshness</strong> (Medium-severity remediation) is complete (proven 2026-06-09):</li><li>Owner: Platform + AI Reliability</li><li><strong>Action 1 complete (2026-06-09):</strong> `/api/ai/query` now returns citation metadata, coverage, and explicit refusal state, locked by `tests/api/ai-query.test.ts` and `tests/quality/cite-or-refuse-conformance.test.ts`.</li><li><strong>Action 2 complete (2026-06-09):</strong> `/api/ai/query` and `/api/ai/chat` now emit `retrievedAt` + `citationFreshness` diagnostics and refuse stale evidence via policy-backed route tests.</li><li>Scope:</li><li>Enforce same cite-or-refuse behavior beyond `/api/ai/chat` so `/api/ai/query` emits stable evidence metadata and refuses under coverage/freshness thresholds.</li><li>Keep `/api/ai/chat` grounded response semantics while adding the shared freshness guard.</li><li>Acceptance:</li><li>`/api/ai/query` returns `{ answer, citations, coverage, citationFreshness, refusalReason? }` with `entityId`, `propertyPath`, `sourceUrl`, and `retrievedAt` in cited outputs.</li><li>Under-cited or stale-evidence answers return explicit refusal and reason.</li><li>Regression test coverage proves chat/query parity and stale-evidence failure modes.</li><li>Proof packet:</li><li>`tests/api/ai-query.test.ts`, `tests/api/ai-chat.test.ts`, and `tests/quality/cite-or-refuse-conformance.test.ts` cover cited success, coverage refusal, and freshness refusal behavior.</li><li>Close-out packet synchronizes `docs/risk-register.md`, `CLAUDE.md`, `README.md`, and this roadmap with evidence proofs.</li><li>[x] ✅ <strong>RSI-6: AI eval drift baselines include citation freshness</strong> (Medium-severity remediation) is complete (proven 2026-06-09):</li><li>`src/services/ai-eval-harness.ts` now scores `citationFreshness` from actual citation/source timestamps instead of treating retrieval time as always fresh.</li><li>`src/services/ai-eval-regression.ts`, `scripts/ai-eval-gate.ts`, and `config/ai-eval-regression-policy.json` now baseline, persist, print, and fail-fast on `citationFreshnessDrop`.</li><li>`evals/golden-museum-questions.v1.json` and `docs/evals/golden-museum-questions.md` now declare `citationFreshnessThreshold = 0.95`.</li><li>Proof packet: `tests/services/ai-eval-harness.test.ts`, `tests/services/ai-eval-regression.test.ts`, `tests/services/ai-eval-artifacts.test.ts`, `tests/quality/ai-eval-golden-dataset.test.ts`, plus direct AI eval gate output with `citationFreshness=1` and `citationFreshnessDrop=0`.</li><li>[x] ✅ <strong>RSI-7: AI eval summary badges + aging-pressure alerting</strong> (Medium-severity remediation) is complete (proven 2026-06-09):</li><li>`src/services/ai-eval-artifacts.ts` now renders `artifacts/evals/summary.md` with status, faithfulness, relevance, citation accuracy, `citationFreshness`, pass-rate badges, artifact links, and alerts.</li><li>`src/services/ai-eval-harness.ts` now persists citation freshness aging (`oldestAgeDays`, `oldestAgeRatio`, `maxAgeDays`) for trend-aware pressure detection.</li><li>`.github/workflows/ai-eval-gate.yml` now appends the summary to `$GITHUB_STEP_SUMMARY` and uploads `artifacts/evals/` for CI inspection.</li><li>Proof packet: `tests/services/ai-eval-artifacts.test.ts`, plus direct AI eval gate output with `summary=artifacts/evals/summary.md`, `citationFreshness=1`, and `oldestAgeRatio=0`.</li><li>[x] ✅ <strong>RSI-8: AI eval artifact dashboard visibility</strong> (Medium-severity remediation) is complete (proven 2026-06-09):</li><li>`src/services/ai-eval-dashboard.ts` now loads ignored local eval artifacts, latest metrics, trend runs, artifact timestamps, and freshness-aging warnings with explicit empty/partial states.</li><li>`app/(workspace)/ai-evals/page.tsx` now provides a read-only app dashboard for latest eval summary, trend index, freshness-aging state, and active warnings.</li><li>Navigation now exposes the dashboard from the workspace sidebar, primary Workspace menu, and footer.</li><li>Proof packet: `tests/services/ai-eval-dashboard.test.ts` and `tests/pages/ai-evals-page.test.ts`, plus focused system Node test output passing 3 tests.</li><li>[x] ✅ <strong>RSI-9: latest-vs-previous AI eval artifact diff</strong> (Medium-severity remediation) is complete (proven 2026-06-09):</li><li>`src/services/ai-eval-dashboard.ts` now computes latest-vs-previous metric deltas, freshness-aging pressure deltas, status changes, prompt-count changes, identity changes, and compact “what changed” notes.</li><li>`app/(workspace)/ai-evals/page.tsx` now renders a “Latest vs previous run” review section with metric arrows, freshness pressure movement, and fast-review notes.</li><li>Proof packet: `tests/services/ai-eval-dashboard.test.ts` and `tests/pages/ai-evals-page.test.ts`, plus focused system Node test output passing 3 tests.</li><li>[x] ✅ <strong>RSI-10: severity-labeled AI eval diff triage</strong> (Medium-severity remediation) is complete (proven 2026-06-09):</li><li>`src/services/ai-eval-dashboard.ts` now classifies metric deltas, freshness-aging pressure movement, and overall latest-vs-previous diff priority as `regression`, `watch`, `stable`, or `improved`.</li><li>`app/(workspace)/ai-evals/page.tsx` now renders priority labels and visible metric/aging threshold pills so review starts with severity instead of raw deltas only.</li><li>Proof packet: `tests/services/ai-eval-dashboard.test.ts` and `tests/pages/ai-evals-page.test.ts`, plus focused system Node output passing 3 tests, `pnpm test` passing 787/249, `pnpm lint` passing with one existing warning, and production Next build passing via system Node.</li><li>[x] ✅ <strong>RSI-11: policy-driven AI eval priority visibility</strong> (Medium-severity remediation) is complete (proven 2026-06-09):</li><li>`config/ai-eval-regression-policy.json` now owns diff severity thresholds consumed by dashboard and CI summary generation.</li><li>`app/(workspace)/ai-evals/page.tsx` now shows last-N severity distribution across `regression`, `watch`, `stable`, and `improved` comparisons.</li><li>`artifacts/evals/summary.md` now includes CI-visible review priority when at least two retained eval runs exist.</li><li>Proof packet: `tests/services/ai-eval-dashboard.test.ts`, `tests/services/ai-eval-artifacts.test.ts`, and `tests/pages/ai-evals-page.test.ts`, plus focused system Node output passing 8 tests, `pnpm test` passing 788/249, `pnpm lint` passing with one existing warning, AI eval gate printing `reviewPriority: stable`, and production Next build passing via system Node.</li><li>[x] ✅ <strong>RSI-12: AI eval agent-summary reliability</strong> (Medium-severity remediation) is complete (proven 2026-06-09):</li><li>`src/services/ai-eval-severity.ts` now validates `diffSeverityPolicy` shape/order and fails malformed policy with explicit errors.</li><li>`/api/ai-evals/summary` now exposes agent-ready JSON with latest run, review priority, severity distribution, severity history, alerts, and artifact links.</li><li>`app/(workspace)/ai-evals/page.tsx` now renders compact severity sparkline and latest-vs-previous comparison history for fast trend review.</li><li>Proof packet: `tests/services/ai-eval-severity.test.ts`, `tests/api/ai-evals-summary.test.ts`, `tests/services/ai-eval-dashboard.test.ts`, `tests/services/ai-eval-artifacts.test.ts`, and `tests/pages/ai-evals-page.test.ts`, plus focused system Node output passing 13 tests, `pnpm test` passing 793/251, `pnpm lint` passing with one existing warning, AI eval gate printing `reviewPriority: stable`, and production Next build confirming `/api/ai-evals/summary`.</li><li>[x] ✅ <strong>RSI-13: AI eval contract + CI annotation reliability</strong> (Medium-severity remediation) is complete (proven 2026-06-09):</li><li>`src/contracts/zod/ai-eval-summary.ts` now defines the reusable agent JSON contract and OpenAPI schema for `/api/ai-evals/summary`.</li><li>`config/ai-eval-regression-policy.json` now owns `severityHistoryPolicy.maxComparisons`, which drives dashboard distribution/history and agent JSON window metadata.</li><li>`scripts/ai-eval-gate.ts` now emits a GitHub PR warning annotation when review priority is `watch` or `regression`, with workflow path filters covering `/api/ai-evals`, policy, and contract changes.</li><li>Proof packet: `tests/api/ai-evals-summary.test.ts`, `tests/api/openapi.test.ts`, `tests/services/ai-eval-severity.test.ts`, `tests/services/ai-eval-dashboard.test.ts`, `tests/services/ai-eval-artifacts.test.ts`, and `tests/pages/ai-evals-page.test.ts`, plus focused system Node output passing 18 tests, `pnpm test` passing 796/251, `pnpm lint` passing with one existing warning, AI eval gate printing `reviewPriority: stable`, and production Next build confirming `/api/ai-evals/summary`.</li><li>[x] ✅ <strong>RSI-14: AI eval version/pruning hygiene</strong> (Medium-severity remediation) is complete (proven 2026-06-09):</li><li>`/api/ai-evals/summary` now returns `schemaVersion: 1`, and `aiEvalSummaryResponseSchema` rejects unsupported versions before agents consume the payload.</li><li>`docs/evals/golden-museum-questions.md` publishes exact GitHub CI annotation examples for `regression` and `watch`, with snapshot assertions keeping docs and formatter output aligned.</li><li>`src/services/ai-eval-artifacts.ts` now prunes orphaned run JSON outside the retained trend window while preserving retained run files and non-JSON notes.</li><li>Proof packet: `tests/api/ai-evals-summary.test.ts`, `tests/api/openapi.test.ts`, and `tests/services/ai-eval-artifacts.test.ts`, plus focused system Node output passing 22 tests, `pnpm test` passing 800/251, `pnpm lint` passing with one existing warning, AI eval gate printing `reviewPriority: stable`, and production Next build confirming `/api/ai-evals/summary`.</li><li>[x] ✅ <strong>RSI-15: AI eval migration/reporting visibility</strong> (Medium-severity remediation) is complete (proven 2026-06-09):</li><li>`src/contracts/zod/ai-eval-summary.ts` now includes future `schemaVersion: 2` migration notes, with v1 accepted and planned v2 rejected through fixture compatibility tests.</li><li>`src/services/ai-eval-artifacts.ts` now returns a retention pruning report with `delete`/`dry-run` mode and retained/orphaned/deleted/preserved file counts.</li><li>`artifacts/evals/summary.md` now surfaces latest CI annotation status and retention pruning status for PR/build reviewers.</li><li>Proof packet: `tests/api/ai-evals-summary.test.ts`, `tests/services/ai-eval-artifacts.test.ts`, and `tests/fixtures/ai-eval-summary/*`, plus focused system Node output passing 24 tests, `pnpm test` passing 802/251, `pnpm lint` passing with one existing warning, AI eval gate printing `reviewPriority: stable`, and production Next build confirming `/api/ai-evals/summary`.</li><li>[x] ✅ <strong>RSI-16: AI eval summary artifact/schema visibility</strong> (Medium-severity remediation) is complete (proven 2026-06-09):</li><li>`tests/fixtures/ai-eval-summary/summary-snapshot.md` now locks the generated CI summary markdown, proving `summary.md` stays reviewable and stable.</li><li>`/api/ai-evals/summary` now exposes the latest `retentionPruneReport` for agents, including delete/dry-run mode and retained/orphaned/deleted/preserved counts.</li><li>`/api/openapi` now includes the AI eval summary schema migration compatibility table so future `schemaVersion` upgrades are discoverable from the contract surface.</li><li>Proof packet: `tests/api/ai-evals-summary.test.ts`, `tests/api/openapi.test.ts`, `tests/services/ai-eval-artifacts.test.ts`, `tests/services/ai-eval-dashboard.test.ts`, and `tests/fixtures/ai-eval-summary/summary-snapshot.md`, plus focused system Node output passing 25 tests, `pnpm test` passing 803/251, `pnpm lint` passing with one existing warning, AI eval gate printing `reviewPriority: stable`, and production Next build confirming `/api/ai-evals/summary`.</li><li>[x] ✅ <strong>RSI-17: Visual ETL Mapper AI-assist safety</strong> (Medium-severity remediation) is complete (proven 2026-06-09):</li><li>`/api/ai/mapping-assist` now returns review-ready, contract-valid `MappingTemplate` drafts from source columns with confidence, rationale, standards anchors, and unmapped-column diagnostics.</li><li>`/etl/mapper` now exposes a &quot;Suggest mapping with AI&quot; action while keeping generated mappings review-only before any ingestion activation.</li><li>Unknown columns are surfaced as diagnostics instead of invented mappings.</li><li>Proof packet: `tests/services/mapping-assist.test.ts`, `tests/api/ai-mapping-assist.test.ts`, `tests/components/etl-mapper-config.test.ts`, and `tests/api/openapi.test.ts`, plus focused system Node output passing 7 mapper-assist tests and 2 OpenAPI tests, `pnpm test` passing 809/253, `pnpm lint` passing with one existing warning, AI eval gate printing `reviewPriority: stable`, and production Next build confirming `/api/ai/mapping-assist`.</li><li>[x] ✅ <strong>RSI-18: mapper-assist fixture/schema/importability hardening</strong> (Medium-severity remediation) is complete (proven 2026-06-09):</li><li>`tests/fixtures/mapping-assist/tricky-columns.json` now locks tricky rights/credit/sensitive columns so mapper assist cannot invent unsafe Linked Art target paths.</li><li>`src/utils/etl-mapper-assist.ts` and `/etl/mapper` now support importing returned suggestions as reviewable ReactFlow draft nodes/edges.</li><li>`/api/openapi` now exposes `MappingAssistResponse` and references it from `/api/ai/mapping-assist`.</li><li>Proof packet: `tests/services/mapping-assist.test.ts`, `tests/utils/etl-mapper-assist.test.ts`, `tests/components/etl-mapper-config.test.ts`, `tests/api/openapi.test.ts`, and `tests/api/ai-mapping-assist.test.ts`, plus focused system Node output passing 11 tests, `pnpm test` passing 811/254, `pnpm lint` passing with one existing warning, AI eval gate printing `reviewPriority: stable`, and production Next build confirming `/api/ai/mapping-assist`.</li><li>[x] ✅ <strong>RSI-19: provider-family/browser/request-schema mapper hardening</strong> (Medium-severity remediation) is complete (proven 2026-06-09):</li><li>`tests/fixtures/mapping-assist/provider-families.json` now covers Met, Getty, and Rijks-style mapper columns with allowed-path and must-stay-unmapped assertions.</li><li>`scripts/smoke-etl-mapper-assist.ts` and `pnpm smoke:etl:mapper-assist` now provide a Playwright browser smoke for `/etl/mapper` assist generation plus draft import.</li><li>`/api/openapi` now exposes `MappingAssistRequest` and attaches it to the `/api/ai/mapping-assist` POST request body.</li><li>Proof packet: `tests/services/mapping-assist.test.ts`, `tests/scripts/etl-mapper-smoke-script.test.ts`, and `tests/api/openapi.test.ts`, plus focused system Node output passing 7 tests, `pnpm smoke:etl:mapper-assist` passing against `http://localhost:3001/en`, `pnpm test` passing 813/255, `pnpm lint` passing with one existing warning, AI eval gate printing `reviewPriority: stable`, and production Next build confirming `/api/ai/mapping-assist`.</li><li>[x] ✅ <strong>RSI-20: negative mapper fixtures, visual screenshot, and API-doc examples</strong> (Medium-severity remediation) is complete (proven 2026-06-09):</li><li>`tests/fixtures/mapping-assist/negative-provider-families.json` now locks near-miss Met/Getty/Rijks columns so rights, credit, restriction, sensitivity, donor, and flag wording cannot trigger unsafe suggestions.</li><li>`scripts/smoke-etl-mapper-assist.ts` now waits on the mapping-assist POST, imports the draft, and writes `artifacts/smoke/etl-mapper-assist-imported.png` with animations disabled.</li><li>`/api/docs` now includes concrete mapping-assist request and response examples next to the Swagger UI entry point.</li><li>Proof packet: `tests/services/mapping-assist.test.ts`, `tests/scripts/etl-mapper-smoke-script.test.ts`, and `tests/api/docs.test.ts`, plus focused system Node output passing 11 tests, `pnpm smoke:etl:mapper-assist` passing against `http://localhost:3001/en`, `pnpm test` passing 814/255, `pnpm lint` passing with one existing warning, AI eval gate printing `reviewPriority: stable`, and production Next build passing.</li><li>[x] ✅ <strong>RSI-21: mapper layout, OpenAPI-sourced docs examples, and confidence policy</strong> (Medium-severity remediation) is complete (proven 2026-06-09):</li><li>`app/globals.css` now gives mapper actions a full-width wrapped row with no button overlap in the refreshed screenshot.</li><li>`app/api/docs/route.ts` now renders mapping-assist request/response examples from `/api/openapi` instead of duplicating static JSON.</li><li>`src/services/mapping-assist.ts` now applies a minimum confidence policy so lower-confidence accession/place/description patterns stay diagnostics-only.</li><li>Proof packet: `tests/components/etl-mapper-config.test.ts`, `tests/api/docs.test.ts`, and `tests/services/mapping-assist.test.ts`, plus focused system Node output passing 15 tests, `pnpm smoke:etl:mapper-assist` refreshing `artifacts/smoke/etl-mapper-assist-imported.png`, `pnpm test` passing 817/255, `pnpm lint` passing with one existing warning, AI eval gate printing `reviewPriority: stable`, and production Next build passing.</li><li>[x] ✅ <strong>RSI-22: public source narrative and trust uplift</strong> (Medium-severity remediation) is complete (proven 2026-06-09):</li><li>`app/datasets/page.tsx` now presents a public source-network narrative backed by `getProviderCapabilities`, not copied prototype constants.</li><li>`app/about/page.tsx` and `app/projects/page.tsx` now migrate the sibling `meta-museum-art` mission/project surfaces into native Next pages while replacing coming-soon/static project cards with live source-network, Linked Art workbench, and Meta Wiki Art workflow links.</li><li>`src/services/site-metadata.ts` centralizes OpenGraph/Twitter metadata with a reviewed local image, and footer navigation exposes Contact/Privacy/Terms plus asset provenance.</li><li>`docs/asset-provenance.md` tracks all preserved sibling visual assets with SHA-256 hashes while marking placeholder thumbnails as excluded from public use and keeping copied legal text out.</li><li>Proof packet: `tests/services/public-source-narrative.test.ts`, `tests/pages/public-source-pages.test.ts`, focused RSI-22 test output passing 6/2 plus follow-up `pnpm test -- tests/pages/public-source-pages.test.ts` passing 851/267 on 2026-06-09, `pnpm lint` passing with one existing warning, `pnpm build` passing, and screenshot proof at `artifacts/smoke/datasets-page.png`.</li><li>[x] ✅ <strong>RSI-23: public-source agent API and trust smoke hardening</strong> (Medium-severity remediation) is complete (proven 2026-06-09):</li><li>`/api/public-sources/summary` now exposes schema-versioned agent JSON for source stats, provider capability flags, and imported asset provenance.</li><li>`docs/asset-provenance.md` and `src/contracts/zod/public-sources-summary.ts` now enforce explicit license-review statuses so unknown asset rows fail.</li><li>`pnpm smoke:public-trust` captures browser screenshots for `/datasets`, `/contact`, `/privacy`, and `/terms`; the nested `meta-museum-art` prototype copy was removed after all images were preserved and inventoried.</li><li>Proof packet: `tests/api/public-sources-summary.test.ts`, `tests/services/public-source-narrative.test.ts`, `tests/scripts/public-trust-smoke-script.test.ts`, focused RSI-23 output passing 6/3, `pnpm smoke:public-trust` passing against `http://localhost:3001`, `pnpm test` passing 827/259, `pnpm lint` passing with one existing warning, and `pnpm build` passing.</li><li>[x] ✅ <strong>RSI-24: OpenAPI, checksum drift, and screenshot retention hardening</strong> (Medium-severity remediation) is complete (proven 2026-06-09):</li><li>`/api/openapi` now includes `PublicSourcesSummaryResponse` and references it from `/api/public-sources/summary`.</li><li>Imported public-source assets now fail tests when their SHA-256 hashes drift from `docs/asset-provenance.md`.</li><li>`pnpm smoke:public-trust` now writes timestamped screenshot runs, latest copies, previous-run links, a summary JSON, and prunes old runs outside the retention window.</li><li>Proof packet: `tests/api/openapi.test.ts`, `tests/services/public-source-narrative.test.ts`, `tests/services/public-trust-smoke-artifacts.test.ts`, `tests/scripts/public-trust-smoke-script.test.ts`, focused RSI-24 output passing 6/5, `pnpm smoke:public-trust` passing against `http://localhost:3001`, `pnpm test` passing 828/260, `pnpm lint` passing with one existing warning, and `pnpm build` passing.</li><li>[x] ✅ <strong>RSI-25: public trust docs, diff metadata, and CI artifact visibility</strong> (Medium-severity remediation) is complete (proven 2026-06-09):</li><li>`/api/docs` now renders the `/api/public-sources/summary` response example from `/api/openapi`, keeping examples single-source for humans and agents.</li><li>Public trust smoke artifacts now include latest-vs-previous checksum/byte diff metadata per screenshot plus CI-ready summary markdown.</li><li>`.github/workflows/public-trust-smoke.yml` now builds, runs `pnpm smoke:public-trust`, appends public trust summary links to `$GITHUB_STEP_SUMMARY`, and uploads `public-trust-smoke-artifacts`.</li><li>Proof packet: `tests/api/docs.test.ts`, `tests/api/openapi.test.ts`, `tests/services/public-trust-smoke-artifacts.test.ts`, `tests/services/public-trust-smoke-ci-summary.test.ts`, `tests/scripts/public-trust-smoke-script.test.ts`, `tests/scripts/public-trust-ci-workflow.test.ts`, focused RSI-25 output passing 12/10, `pnpm smoke:public-trust` passing against temporary `http://localhost:3001`, `pnpm test` passing 830/262, `pnpm lint` passing with one existing warning, and `pnpm build` passing.</li><li>[x] ✅ <strong>RSI-26: pixel-diff thresholds, public trust summary API, and main CI artifact links</strong> (Medium-severity remediation) is complete (proven 2026-06-09):</li><li>`pnpm smoke:public-trust` now decodes PNG screenshots, computes changed-pixel ratios, and fails when `PUBLIC_TRUST_SCREENSHOT_PIXEL_DIFF_THRESHOLD` is exceeded.</li><li>`/api/public-trust/summary` now exposes schema-versioned latest public trust smoke artifacts and pixel-diff status for agents.</li><li>`.github/workflows/ci.yml` now runs public trust smoke, appends summary links to `$GITHUB_STEP_SUMMARY`, and uploads `public-trust-smoke-artifacts`.</li><li>Proof packet: `tests/services/public-trust-smoke-artifacts.test.ts`, `tests/api/public-trust-summary.test.ts`, `tests/api/openapi.test.ts`, `tests/scripts/public-trust-smoke-script.test.ts`, `tests/scripts/public-trust-ci-workflow.test.ts`, focused RSI-26 output passing 10/7, `pnpm smoke:public-trust` passing with `unchanged=4` and `pixel failures=0`, `pnpm test` passing 834/263, `pnpm lint` passing with one existing warning, and `pnpm build` passing.</li><li>[x] ✅ <strong>RSI-27: public trust per-page thresholds, OpenAPI docs example, and retention badge</strong> (Medium-severity remediation) is complete (proven 2026-06-09):</li><li>Public trust smoke now applies stricter `/datasets` pixel drift policy (`0.005`) than Contact/Privacy/Terms legal pages (`0.02`).</li><li>`/api/docs` now renders the `/api/public-trust/summary` response example from `/api/openapi`.</li><li>Public trust CI summary now includes a retention badge snapshot-locked by `tests/fixtures/public-trust-summary/summary-snapshot.md`.</li><li>Proof packet: `tests/services/public-trust-smoke-artifacts.test.ts`, `tests/scripts/public-trust-smoke-script.test.ts`, `tests/services/public-trust-smoke-ci-summary.test.ts`, `tests/fixtures/public-trust-summary/summary-snapshot.md`, `tests/api/docs.test.ts`, `tests/api/openapi.test.ts`, focused RSI-27 output passing 13/9, `pnpm smoke:public-trust` passing with per-page thresholds, `unchanged=4`, and `pixel failures=0`, `pnpm test` passing 835/263, `pnpm lint` passing with one existing warning, and `pnpm build` passing.</li><li>[x] ✅ <strong>RSI-28: JSON public trust threshold policy, agent-visible policy, and CI drift annotations</strong> (Medium-severity remediation) is complete (proven 2026-06-09):</li><li>Public trust smoke policy is now persisted in `config/public-trust-smoke-policy.json` and consumed by `scripts/smoke-public-trust-pages.ts`.</li><li>`/api/public-trust/summary` now exposes the applied threshold policy for agents alongside latest smoke artifacts.</li><li>CI summary tooling now emits warning annotations when screenshots change but remain under their configured threshold.</li><li>Proof packet: `config/public-trust-smoke-policy.json`, `src/services/public-trust-smoke-policy.ts`, `scripts/smoke-public-trust-pages.ts`, `src/services/public-trust-summary.ts`, `src/contracts/zod/public-trust-summary.ts`, `src/services/public-trust-smoke-ci-summary.ts`, `tests/services/public-trust-smoke-policy.test.ts`, `tests/scripts/public-trust-smoke-script.test.ts`, `tests/api/public-trust-summary.test.ts`, `tests/services/public-trust-smoke-ci-summary.test.ts`, `tests/scripts/public-trust-ci-workflow.test.ts`, focused RSI-28 output passing 20/12, `pnpm smoke:public-trust` passing with JSON policy thresholds, `unchanged=4`, and `pixel failures=0`, `pnpm test` passing 838/264, `pnpm lint` passing with one existing warning, and `pnpm build` passing.</li><li>[x] ✅ <strong>RSI-29: public trust reviewer rationale, schema rejection, and severity-grouped PR summaries</strong> (Medium-severity remediation) is complete (proven 2026-06-09):</li><li>Public trust policy pages now carry `reviewSeverity`, `reviewerNote`, and `reasonCodes`.</li><li>`/api/public-trust/summary` now exposes reviewer rationale metadata in the applied threshold policy for agents.</li><li>Public trust CI summaries and warning annotations now group under-threshold visual drift by high/medium/low route severity.</li><li>Proof packet: `config/public-trust-smoke-policy.json`, `src/services/public-trust-smoke-policy.ts`, `src/services/public-trust-summary.ts`, `src/contracts/zod/public-trust-summary.ts`, `scripts/smoke-public-trust-pages.ts`, `src/services/public-trust-smoke-ci-summary.ts`, `tests/services/public-trust-smoke-policy.test.ts`, `tests/api/public-trust-summary.test.ts`, `tests/services/public-trust-smoke-ci-summary.test.ts`, `tests/fixtures/public-trust-summary/summary-snapshot.md`, focused RSI-29 output passing 18/11 plus CI-summary focused retest 2/1, `pnpm exec start-server-and-test &quot;pnpm dev&quot; http://localhost:3000 &quot;pnpm smoke:public-trust&quot;` passing with JSON policy metadata and `pixel failures=0`, `pnpm test` passing 839/264, `pnpm lint` passing with one existing warning, and `pnpm build` passing.</li><li>[x] ✅ <strong>RSI-30: owner/reviewer initials, schema v2 fixture, and grouped annotation snapshot</strong> (Medium-severity remediation) is complete (proven 2026-06-09):</li><li>Public trust policy pages now carry `ownerInitials` and `reviewerInitials` alongside severity, notes, and reason codes.</li><li>`/api/public-trust/summary` and CI drift summary rows now expose owner/reviewer initials for fast review routing.</li><li>Planned `schemaVersion: 2` policy fixture and grouped warning annotation snapshot are now committed as executable contract evidence.</li><li>Proof packet: `config/public-trust-smoke-policy.json`, `src/services/public-trust-smoke-policy.ts`, `src/services/public-trust-summary.ts`, `src/contracts/zod/public-trust-summary.ts`, `src/services/public-trust-smoke-ci-summary.ts`, `tests/fixtures/public-trust-policy/schema-v2-planned.json`, `tests/fixtures/public-trust-summary/grouped-annotations-snapshot.txt`, `tests/services/public-trust-smoke-policy.test.ts`, `tests/api/public-trust-summary.test.ts`, `tests/services/public-trust-smoke-ci-summary.test.ts`, focused RSI-30 tests passing 15/10, `pnpm exec start-server-and-test &quot;pnpm dev&quot; http://localhost:3000 &quot;pnpm smoke:public-trust&quot;` passing with `unchanged=4` and `pixel failures=0`, isolated transient `tests/api/artworks/by-id.test.ts` retest passing, final `pnpm test` passing 839/264, `pnpm lint` passing with one existing warning, and `pnpm build` passing.</li><li>[x] ✅ <strong>RSI-1: Provider/pipeline boundary drift hardening</strong> (High-severity remediation) is closed and proven:</li><li>boundary contract test passes with allowed shared imports only,</li><li>full `pnpm test` + `pnpm lint` + `pnpm build` cycle passed in-cycle,</li><li>close-out evidence synchronized in `CLAUDE.md`, `README.md`, and this roadmap.</li><li>[x] ✅ <strong>RSI-2: UI journey automation scope</strong> (Medium-severity remediation) is closed and proven:</li><li>matrix automation now spans role/provider combinations (`pnpm smoke:explore:matrix`), and `/api/objects`, `/api/works`, `/api/agents`, `/api/places`, `/api/sets` route assertions verify positive + negative paths for imported records,</li><li>smoke probe evidence and status updates are synchronized in `CLAUDE.md`, this roadmap, and `README.md`.</li><li>[x] ✅ <strong>RSI-3: Single-file and process-complexity reduction</strong> (Low-severity remediation) is complete (proven 2026-06-09):</li><li>Owner map and top-complexity target inventory are now finalized in `docs/risk-register.md` (Action 1 complete).</li><li>Action 2 is complete: `src/services/publish-queue-worker.ts` split into helper modules with existing tests preserved.</li><li>Action 3 is complete: `src/services/issues.ts` split into focused modules under `src/services/issues/` with behavior preserved.</li><li>Action 4 is complete: `src/services/outbox.ts` split into focused modules under `src/services/outbox/` with behavior preserved.</li><li>Action 5 is complete: `src/services/reconciliation.ts` split into focused modules under `src/services/reconciliation/` with behavior preserved.</li><li>Action 6 is complete: `src/services/wiki-publish.ts` split into focused modules under `src/services/wiki-publish/` with behavior preserved.</li><li>Action 7 is complete: `src/services/monitoring-telemetry.ts` split into focused modules under `src/services/monitoring-telemetry/` with behavior preserved.</li><li>Proof packet: `pnpm test`, `pnpm lint`, and `pnpm build` for the closeout cycle, plus synchronized updates in `CLAUDE.md`, `docs/roadmap.md`, and `README.md` with this evidence path.</li><li>Action 8 is complete: `scripts/authority-cache-refresh.ts` split into focused modules under `scripts/authority-cache-refresh/` with behavior preserved.</li><li>Proof packet: `pnpm test`, `pnpm lint`, and `pnpm build` with synchronized updates in `CLAUDE.md`, `docs/roadmap.md`, and `README.md`.</li><li>Action 9 is complete: `src/services/ai-layer.ts` split into focused modules under `src/services/ai-layer/` with API preserved in the facade.</li><li>Proof packet: `pnpm test`, `pnpm lint`, and `pnpm build` all passed, with close-out updates synchronized in `CLAUDE.md`, `README.md`, and `docs/risk-register.md`.</li><li>[x] ✅ <strong>RSI-4: Chat grounding and citation enforcement</strong> (Medium-severity remediation) is complete (proven 2026-06-09):</li><li>`/api/ai/chat` now returns sentence-level grounded citations (`[entityId, propertyPath]`) and refuses output when citation coverage is incomplete.</li><li>Evidence is implemented in `app/api/ai/chat/route.ts` and `src/services/ai-chat.ts`.</li><li>Proof packet: `tests/api/ai-chat.test.ts`, `pnpm test` (full suite), `pnpm lint`, and `pnpm build`; close-out updates synchronized in `CLAUDE.md`, `README.md`, and `docs/risk-register.md`.</li><li>[x] ✅ Expand HAL `_links` discoverability coverage from representative routes to all public entity-role routes as they land (enforced through protocol + provider conformance suites and `hal-entity-discoverability-conformance` quality checks).</li><li>[x] ✅ Add search-relation conformance breadth tests across additional provider search endpoints (beyond representative NGA/RKD/facade checks) with pagination drift assertions.</li><li>Evidence: <a href=\"/C:/Projects/metamuseum/tests/quality/hal-search-relations-conformance.test.ts\" class=\"doc-link\">`tests/quality/hal-search-relations-conformance.test.ts`</a> now validates relation and pagination behavior for Louvre, Harvard, Smithsonian, V&amp;A, Princeton, Europeana, AIC, CMA, and Rijks routes in addition to existing representative checks.</li><li>[x] ✅ Keep execution-policy gates strict: no provider/validation merges without standards mapping + fixture anchors, and no protocol-affecting merges without conformance coverage.</li><li>Evidence: <a href=\"/C:/Projects/metamuseum/tests/quality/execution-policy-gates.test.ts\" class=\"doc-link\">`tests/quality/execution-policy-gates.test.ts`</a>, <a href=\"/C:/Projects/metamuseum/.github/pull_request_template.md\" class=\"doc-link\">`.github/pull_request_template.md`</a>.</li></ul>\n<p>Suggested branch name (used): `codex/era-c1-hal-search-conformance-breadth`.</p>\n<p>&lt;!-- 2026-07-01T18:13:00Z fix: TS6 compat --&gt;</p>\n<p>&lt;!-- 2026-07-01T18:28:55Z style: homepage color refresh --&gt;</p>\n<p>&lt;!-- last-session: 2026-07-01T19:07:54Z --&gt;</p>","updatedAt":"2026-07-07T00:00:00.000Z","checksum":"988d4c1562ff147908722d64a188747f4d74eedb1b3245a3db7ecdbdfd1389e9","checksumPrefix":"988d4c1562ff","anchorCount":18,"lineCount":641,"rawUrl":"/api/docs/content?path=roadmap.md","htmlUrl":"/docs?doc=roadmap.md","apiUrl":"/api/docs/content?path=roadmap.md"}