{"id":"ops/external-evidence-request-pack","relativePath":"ops/external-evidence-request-pack.md","title":"External Evidence Request Pack","markdown":"# External Evidence Request Pack\n\nUse this pack when moving the remaining 10/10 blockers from scaffolded proof to real public evidence. Do not use demo, fixture, placeholder, sample, smoke, test, localhost, or private-network evidence for these gates.\n\n## Current Order\n\n1. Keep the nightly Era C workflow green and committing rolling evidence inputs.\n2. Let public SLO and uptime windows fill to 30 distinct days.\n3. Send one real pilot outreach and record it.\n4. Generate the buyer-specific pilot capture pack, convert one pilot to an invoice-backed manual entitlement, then record activation, support, KPI, retention, and gross-margin evidence.\n5. Ask three external ActivityStreams consumers to read `/api/activity` with stable declared IDs and enough page depth to observe `Create`, `Update`, and `Delete` activity types.\n6. Ask those same consumers to register durable HTTPS callbacks and provide recent 2xx verification evidence.\n7. Rerun `pnpm review:goals:local`; use `pnpm review:goals:check` only when strict external evidence is expected to pass.\n\n## Pilot Ask\n\nSend a short pilot note like:\n\n```text\nSubject: Managed Linked Art launch pilot\n\nWe are inviting one collection partner into a managed Linked Art launch pilot for Meta Museum.\n\nScope:\n- ingest one collection export into a hosted workspace\n- produce a Linked Art API/public browse surface\n- deliver a data-quality and rights/provenance review packet\n- include one monthly evidence packet with activation, support, KPI, retention, and gross-margin proof\n\nIf this is useful, the next step is a signed fixed-scope pilot and manual invoice reference so we can create the tenant entitlement and start the evidence ledger.\n```\n\nRecord sent outreach:\n\n```powershell\npnpm pilot:outreach --account=<real-account-id> --stage=sent --occurred-at=<ISO timestamp> --owner=<owner> --evidence=channel=<email-or-crm> --evidence=messageRef=<crm-or-email-ref> --evidence=followUpAt=<YYYY-MM-DD>\n```\n\nGenerate the buyer-specific capture checklist before creating the packet:\n\n```powershell\npnpm pilot:buyer-pack -- --account <real-account-id> --tenant <tenant-id> --organization \"<buyer organization>\" --invoice-ref <real-invoice-ref> --owner \"<owner>\"\n```\n\nThis writes `artifacts/pilot-evidence/pilot-buyer-onboarding-pack-latest.md`,\n`.json`, and a timestamped\n`artifacts/pilot-evidence/runs/pilot-buyer-onboarding-pack-<timestamp>.json`\naudit copy with the exact outreach, activation, support, KPI, packaging, and\npacket verification commands. Without real buyer and invoice fields, the pack\nremains `needs-buyer-evidence`.\nWith real buyer fields, use the generated `acceptanceRows` as the paid-pilot\nledger. Each row stays pending until outreach, invoice-backed entitlement,\nactivation, support load, KPI completeness, retention signal, gross-margin\nproof, and the refreshed strict pilot packet all point to the same real account\nand tenant.\n\nAfter a real pilot is signed, create the manual entitlement through the existing operator path, then record activation and KPI evidence with:\n\n```powershell\npnpm pilot:activation --tenant=<tenant-id> --event=<activation-event> --occurred-at=<ISO timestamp> --evidence=tenantId=<tenant-id> --evidence=evidenceRef=<real-evidence-ref>\npnpm pilot:support --tenant=<tenant-id> --issue=<real-issue-id> --opened-at=<ISO timestamp> --requester=\"<buyer contact>\" --severity=normal --title=\"<support summary>\" --decision-owner=\"<owner>\" --next-response-at=<ISO timestamp> --status=resolved --resolved-at=<ISO timestamp> --resolution-summary=\"<resolution summary>\"\npnpm pilot:support --tenant=<tenant-id> --summary\npnpm pilot:kpi --tenant=<tenant-id> --metric=<metric-id> --value=<number> --measured-at=<ISO timestamp> --source=<real-source> --evidence-ref=<real-evidence-ref> --owner=<owner>\npnpm pilot:evidence --tenant=<tenant-id> --account=<real-account-id> --markdown --check\n```\n\nRequired KPI metrics:\n\n- `pilot.first_value_days`\n- `pilot.imported_record_count`\n- `pilot.customer_view_count`\n- `pilot.support_minutes`\n- `pilot.validation_critical_open_count`\n- `pilot.retention_signal_count`\n- `pilot.gross_margin_percent`\n\nThe final packet must pass because the tenant has real invoice-backed billing, outreach, activation, support, KPI, retention, and gross-margin evidence. A researched account or internal demo is not enough.\n\n## SOTA Section 26 KPI Evidence\n\nExport production KPI inputs with:\n\n```powershell\npnpm monitoring:kpi-evidence:production -- --auto-link <count> --weekly-digest <count> --human-review <count> --drop-candidate <count> --reviewed-auto-linked <count> --accepted-auto-linked <count> --reviewed-precision-source \"production curator review export\"\n```\n\nThen inspect `monitoring/kpi-evidence.json`. Start with\n`diagnostics.handoffSummary`; it should report `ready-to-refresh`, `5/5`\nacceptance rows ready, `4/4` capture rows ready, `0` metric blockers, and the\nnext command pair for public telemetry plus Era C. Its `acceptanceRows` must all\nbe `ready`: production record export, record-enrichment denominator, production\nreconciliation export, reviewed precision counts/source, and strict Era C\nrefresh readiness. These rows only prove the input is production-shaped enough\nfor telemetry; strict KPI proof still requires `pnpm monitoring:telemetry:public`\nand `pnpm era-c:exit-gate:public` to pass the configured thresholds.\n\n## ActivityStreams Consumer Ask\n\nIf a broad community ask has already been posted, record the outreach context\nfirst. This preserves the trail for operators, but it does not satisfy\nActivityStreams adoption proof:\n\n```powershell\npnpm activity:community-outreach -- --channel \"<community/channel>\" --message-ref \"<permalink-or-thread-ref>\" --posted-at \"<ISO timestamp>\" --owner \"<owner>\"\n```\n\nThe generated `activity-community-outreach` artifact remains `strictEvidence:\nfalse`. Strict proof starts only when three partner-owned consumer IDs produce\nfeed-read telemetry and durable callback evidence.\n\nGenerate the current partner handoff artifact first:\n\n```powershell\npnpm activity:partner-pack -- --consumer-id <id-1> --consumer-id <id-2> --consumer-id <id-3>\n```\n\nThis writes `artifacts/activity-syndication/activity-partner-onboarding-pack-latest.md`,\n`.json`, and a timestamped\n`artifacts/activity-syndication/runs/activity-partner-onboarding-pack-<timestamp>.json`\naudit copy with per-consumer feed-read and durable-subscription curl requests.\nWithout three real partner-owned IDs, the pack remains `needs-consumer-ids`.\nWith real IDs, use the generated `acceptanceRows` as the per-partner ledger:\neach row remains pending until declared feed-read evidence, Create/Update/Delete\nactivity-type coverage, a durable HTTPS subscription, recent 2xx callback proof,\nand the refreshed `pnpm activity:syndication:evidence` packet all agree on the\nsame partner-owned consumer ID.\n\nSend each external consumer this request:\n\n```text\nPlease read the Meta Museum ActivityStreams feed with your stable consumer ID so we can verify external syndication adoption:\n\ncurl -H \"Accept: application/activity+json\" \\\n  -H \"x-linked-art-consumer-id: <your-stable-consumer-id>\" \\\n  \"https://www.metamuseum.org/api/activity?limit=100\"\n\ncurl -H \"Accept: application/activity+json\" \\\n  -H \"x-linked-art-consumer-id: <your-stable-consumer-id>\" \\\n  \"https://www.metamuseum.org/api/activity?limit=100&type=Create\"\n\ncurl -H \"Accept: application/activity+json\" \\\n  -H \"x-linked-art-consumer-id: <your-stable-consumer-id>\" \\\n  \"https://www.metamuseum.org/api/activity?limit=100&type=Update\"\n\ncurl -H \"Accept: application/activity+json\" \\\n  -H \"x-linked-art-consumer-id: <your-stable-consumer-id>\" \\\n  \"https://www.metamuseum.org/api/activity?limit=100&type=Delete\"\n\nUse an ID owned by your system, not a test or demo ID. We will verify it appears as a declared external consumer. If `Update` or `Delete` returns zero items, report that explicitly; strict coverage waits until real update or tombstone rows exist in the public feed.\n```\n\nVerify all three IDs:\n\n```powershell\npnpm activity:adoption:matrix -- --base-url https://www.metamuseum.org --consumer-id <id-1> --consumer-id <id-2> --consumer-id <id-3>\n```\n\nIf the public feed still lacks `Update` or `Delete` rows, create only real\nsource events before asking partners to re-read them. A reviewed existing-record\nmetadata correction emits `Update`; a confirmed upstream `404`/`410` tombstone\ncan be recorded with:\n\n```powershell\npnpm activity:tombstone:evidence -- --object-id <canonical-record-uri> --provider <provider-key> --upstream-status 410 --observed-at <ISO timestamp> --evidence-ref artifacts/activity-syndication/<real-upstream-404-or-410-proof>.json\n```\n\n## Durable Subscription Ask\n\nAfter the same consumers are observed, ask each to register a callback:\n\n```bash\ncurl -X POST \"https://www.metamuseum.org/api/activity/subscriptions\" \\\n  -H \"content-type: application/json\" \\\n  -H \"accept: application/activity+json\" \\\n  -H \"x-linked-art-consumer-id: <your-stable-consumer-id>\" \\\n  --data '{\n    \"callbackUrl\": \"https://<public-consumer-host>/<activity-callback-path>\",\n    \"eventTypes\": [\"Create\", \"Update\", \"Delete\"]\n  }'\n```\n\nThen attach recent callback verification evidence to the subscription ledger with a public callback host, 2xx `statusCode`, `verifiedAt`, and a real `evidenceRef`. Recheck:\n\n```powershell\npnpm activity:subscription:verify -- --consumer-id <your-stable-consumer-id> --callback-url https://<public-consumer-host>/<activity-callback-path> --status-code 204 --verified-at <ISO timestamp> --evidence-ref artifacts/activity-syndication/<real-callback-proof>.json\npnpm activity:syndication:evidence\npnpm activity:syndication:check\npnpm era-c:exit-gate:public\n```\n\nThe durable gate passes only when the same three declared external consumer IDs have observed feed-read telemetry covering `Create`, `Update`, and `Delete`, active HTTPS subscriptions covering those same event types, and recent 2xx callback verification evidence.\n\nMetaHistoryBook's verified callback row:\n\n```bash\ncurl -X POST \"https://www.metamuseum.org/api/activity/subscriptions\" \\\n  -H \"content-type: application/json\" \\\n  -H \"accept: application/activity+json\" \\\n  -H \"x-linked-art-consumer-id: metahistorybook-harvester-prod\" \\\n  --data '{\n    \"callbackUrl\": \"https://www.metahistorybook.com/api/metamuseum/callback\",\n    \"eventTypes\": [\"Create\", \"Update\", \"Delete\"],\n    \"signingRequired\": true,\n    \"signingSecretRef\": \"metahistorybook-harvester-prod-v1\"\n  }'\n```\n\nMetaMuseum rechecked liveness, sent one signed production `Create` Activity\npayload, and received `204` from that callback at\n`2026-07-05T17:13:13.312Z`. The proof artifact intentionally omits the HMAC\nsecret and signature value:\n\n```powershell\npnpm activity:subscription:verify -- --consumer-id metahistorybook-harvester-prod --callback-url https://www.metahistorybook.com/api/metamuseum/callback --status-code 204 --verified-at 2026-07-05T17:13:13.312Z --evidence-ref artifacts/activity-syndication/metahistorybook-harvester-prod-callback-2026-07-05T17-13-13-312Z.json\n```\n\nTheir 2026-07-05T16:37Z typed read reported `Create: 108`, `Update: 0`, and\n`Delete: 0`; the explicit zeroes should remain filed as honest partner feedback,\nnot as complete activity-type coverage.\n\n## Reliability Evidence\n\nNightly `.github/workflows/era-c-exit-gate-evidence.yml` now commits compact rolling evidence inputs back to `main`, including the k6 trend and public uptime history. Keep these repository variables configured:\n\n- `METAMUSEUM_EVIDENCE_BASE_URL=https://www.metamuseum.org`\n- `METAMUSEUM_PUBLIC_READ_BASE_URL=https://www.metamuseum.org`\n- `METAMUSEUM_EVIDENCE_IIIF_TILE_URL=<public tile/static image URL>`\n- `METAMUSEUM_ACTIVITY_CONSUMER_IDS=<id-1>,<id-2>,<id-3>` after real consumers exist\n\nDaily review:\n\n```powershell\npnpm longterm:evidence:public\npnpm review:goals:local\n```\n\n`pnpm longterm:evidence:public` also runs the daily maintenance companion for\nthe runway. It identifies failed SLO samples, failed public-read probe paths,\npassing distinct evidence days, the earliest failure-free window date, and the\nreal ActivityStreams consumers still needed; it does not mutate the evidence\nhistory. Use the generated `acceptanceRows` as the 30-day reliability ledger:\nSLO sample depth, SLO failure-free window, uptime observation depth, uptime\navailability, ActivityStreams consumer depth, activity-type coverage, and strict\nlong-term packet refresh must all be `ready` before this lane can support a\nstrict production-readiness claim.\n","sections":[{"level":2,"heading":"Current Order","anchor":"current-order"},{"level":2,"heading":"Pilot Ask","anchor":"pilot-ask"},{"level":2,"heading":"SOTA Section 26 KPI Evidence","anchor":"sota-section-26-kpi-evidence"},{"level":2,"heading":"ActivityStreams Consumer Ask","anchor":"activitystreams-consumer-ask"},{"level":2,"heading":"Durable Subscription Ask","anchor":"durable-subscription-ask"},{"level":2,"heading":"Reliability Evidence","anchor":"reliability-evidence"}],"html":"<h1 id=\"external-evidence-request-pack\">External Evidence Request Pack</h1>\n<p>Use this pack when moving the remaining 10/10 blockers from scaffolded proof to real public evidence. Do not use demo, fixture, placeholder, sample, smoke, test, localhost, or private-network evidence for these gates.</p>\n<h2 id=\"current-order\">Current Order</h2>\n<ol><li>Keep the nightly Era C workflow green and committing rolling evidence inputs.</li></ol>\n<ol><li>Let public SLO and uptime windows fill to 30 distinct days.</li></ol>\n<ol><li>Send one real pilot outreach and record it.</li></ol>\n<ol><li>Generate the buyer-specific pilot capture pack, convert one pilot to an invoice-backed manual entitlement, then record activation, support, KPI, retention, and gross-margin evidence.</li></ol>\n<ol><li>Ask three external ActivityStreams consumers to read `/api/activity` with stable declared IDs and enough page depth to observe `Create`, `Update`, and `Delete` activity types.</li></ol>\n<ol><li>Ask those same consumers to register durable HTTPS callbacks and provide recent 2xx verification evidence.</li></ol>\n<ol><li>Rerun `pnpm review:goals:local`; use `pnpm review:goals:check` only when strict external evidence is expected to pass.</li></ol>\n<h2 id=\"pilot-ask\">Pilot Ask</h2>\n<p>Send a short pilot note like:</p>\n<pre><code>\nSubject: Managed Linked Art launch pilot\n\nWe are inviting one collection partner into a managed Linked Art launch pilot for Meta Museum.\n\nScope:\n- ingest one collection export into a hosted workspace\n- produce a Linked Art API/public browse surface\n- deliver a data-quality and rights/provenance review packet\n- include one monthly evidence packet with activation, support, KPI, retention, and gross-margin proof\n\nIf this is useful, the next step is a signed fixed-scope pilot and manual invoice reference so we can create the tenant entitlement and start the evidence ledger.\n</code></pre>\n<p>Record sent outreach:</p>\n<pre><code>\npnpm pilot:outreach --account=&lt;real-account-id&gt; --stage=sent --occurred-at=&lt;ISO timestamp&gt; --owner=&lt;owner&gt; --evidence=channel=&lt;email-or-crm&gt; --evidence=messageRef=&lt;crm-or-email-ref&gt; --evidence=followUpAt=&lt;YYYY-MM-DD&gt;\n</code></pre>\n<p>Generate the buyer-specific capture checklist before creating the packet:</p>\n<pre><code>\npnpm pilot:buyer-pack -- --account &lt;real-account-id&gt; --tenant &lt;tenant-id&gt; --organization &quot;&lt;buyer organization&gt;&quot; --invoice-ref &lt;real-invoice-ref&gt; --owner &quot;&lt;owner&gt;&quot;\n</code></pre>\n<p>This writes `artifacts/pilot-evidence/pilot-buyer-onboarding-pack-latest.md`,</p>\n<p>`.json`, and a timestamped</p>\n<p>`artifacts/pilot-evidence/runs/pilot-buyer-onboarding-pack-&lt;timestamp&gt;.json`</p>\n<p>audit copy with the exact outreach, activation, support, KPI, packaging, and</p>\n<p>packet verification commands. Without real buyer and invoice fields, the pack</p>\n<p>remains `needs-buyer-evidence`.</p>\n<p>With real buyer fields, use the generated `acceptanceRows` as the paid-pilot</p>\n<p>ledger. Each row stays pending until outreach, invoice-backed entitlement,</p>\n<p>activation, support load, KPI completeness, retention signal, gross-margin</p>\n<p>proof, and the refreshed strict pilot packet all point to the same real account</p>\n<p>and tenant.</p>\n<p>After a real pilot is signed, create the manual entitlement through the existing operator path, then record activation and KPI evidence with:</p>\n<pre><code>\npnpm pilot:activation --tenant=&lt;tenant-id&gt; --event=&lt;activation-event&gt; --occurred-at=&lt;ISO timestamp&gt; --evidence=tenantId=&lt;tenant-id&gt; --evidence=evidenceRef=&lt;real-evidence-ref&gt;\npnpm pilot:support --tenant=&lt;tenant-id&gt; --issue=&lt;real-issue-id&gt; --opened-at=&lt;ISO timestamp&gt; --requester=&quot;&lt;buyer contact&gt;&quot; --severity=normal --title=&quot;&lt;support summary&gt;&quot; --decision-owner=&quot;&lt;owner&gt;&quot; --next-response-at=&lt;ISO timestamp&gt; --status=resolved --resolved-at=&lt;ISO timestamp&gt; --resolution-summary=&quot;&lt;resolution summary&gt;&quot;\npnpm pilot:support --tenant=&lt;tenant-id&gt; --summary\npnpm pilot:kpi --tenant=&lt;tenant-id&gt; --metric=&lt;metric-id&gt; --value=&lt;number&gt; --measured-at=&lt;ISO timestamp&gt; --source=&lt;real-source&gt; --evidence-ref=&lt;real-evidence-ref&gt; --owner=&lt;owner&gt;\npnpm pilot:evidence --tenant=&lt;tenant-id&gt; --account=&lt;real-account-id&gt; --markdown --check\n</code></pre>\n<p>Required KPI metrics:</p>\n<ul><li>`pilot.first_value_days`</li><li>`pilot.imported_record_count`</li><li>`pilot.customer_view_count`</li><li>`pilot.support_minutes`</li><li>`pilot.validation_critical_open_count`</li><li>`pilot.retention_signal_count`</li><li>`pilot.gross_margin_percent`</li></ul>\n<p>The final packet must pass because the tenant has real invoice-backed billing, outreach, activation, support, KPI, retention, and gross-margin evidence. A researched account or internal demo is not enough.</p>\n<h2 id=\"sota-section-26-kpi-evidence\">SOTA Section 26 KPI Evidence</h2>\n<p>Export production KPI inputs with:</p>\n<pre><code>\npnpm monitoring:kpi-evidence:production -- --auto-link &lt;count&gt; --weekly-digest &lt;count&gt; --human-review &lt;count&gt; --drop-candidate &lt;count&gt; --reviewed-auto-linked &lt;count&gt; --accepted-auto-linked &lt;count&gt; --reviewed-precision-source &quot;production curator review export&quot;\n</code></pre>\n<p>Then inspect `monitoring/kpi-evidence.json`. Start with</p>\n<p>`diagnostics.handoffSummary`; it should report `ready-to-refresh`, `5/5`</p>\n<p>acceptance rows ready, `4/4` capture rows ready, `0` metric blockers, and the</p>\n<p>next command pair for public telemetry plus Era C. Its `acceptanceRows` must all</p>\n<p>be `ready`: production record export, record-enrichment denominator, production</p>\n<p>reconciliation export, reviewed precision counts/source, and strict Era C</p>\n<p>refresh readiness. These rows only prove the input is production-shaped enough</p>\n<p>for telemetry; strict KPI proof still requires `pnpm monitoring:telemetry:public`</p>\n<p>and `pnpm era-c:exit-gate:public` to pass the configured thresholds.</p>\n<h2 id=\"activitystreams-consumer-ask\">ActivityStreams Consumer Ask</h2>\n<p>If a broad community ask has already been posted, record the outreach context</p>\n<p>first. This preserves the trail for operators, but it does not satisfy</p>\n<p>ActivityStreams adoption proof:</p>\n<pre><code>\npnpm activity:community-outreach -- --channel &quot;&lt;community/channel&gt;&quot; --message-ref &quot;&lt;permalink-or-thread-ref&gt;&quot; --posted-at &quot;&lt;ISO timestamp&gt;&quot; --owner &quot;&lt;owner&gt;&quot;\n</code></pre>\n<p>The generated `activity-community-outreach` artifact remains `strictEvidence:</p>\n<p>false`. Strict proof starts only when three partner-owned consumer IDs produce</p>\n<p>feed-read telemetry and durable callback evidence.</p>\n<p>Generate the current partner handoff artifact first:</p>\n<pre><code>\npnpm activity:partner-pack -- --consumer-id &lt;id-1&gt; --consumer-id &lt;id-2&gt; --consumer-id &lt;id-3&gt;\n</code></pre>\n<p>This writes `artifacts/activity-syndication/activity-partner-onboarding-pack-latest.md`,</p>\n<p>`.json`, and a timestamped</p>\n<p>`artifacts/activity-syndication/runs/activity-partner-onboarding-pack-&lt;timestamp&gt;.json`</p>\n<p>audit copy with per-consumer feed-read and durable-subscription curl requests.</p>\n<p>Without three real partner-owned IDs, the pack remains `needs-consumer-ids`.</p>\n<p>With real IDs, use the generated `acceptanceRows` as the per-partner ledger:</p>\n<p>each row remains pending until declared feed-read evidence, Create/Update/Delete</p>\n<p>activity-type coverage, a durable HTTPS subscription, recent 2xx callback proof,</p>\n<p>and the refreshed `pnpm activity:syndication:evidence` packet all agree on the</p>\n<p>same partner-owned consumer ID.</p>\n<p>Send each external consumer this request:</p>\n<pre><code>\nPlease read the Meta Museum ActivityStreams feed with your stable consumer ID so we can verify external syndication adoption:\n\ncurl -H &quot;Accept: application/activity+json&quot; \\\n  -H &quot;x-linked-art-consumer-id: &lt;your-stable-consumer-id&gt;&quot; \\\n  &quot;https://www.metamuseum.org/api/activity?limit=100&quot;\n\ncurl -H &quot;Accept: application/activity+json&quot; \\\n  -H &quot;x-linked-art-consumer-id: &lt;your-stable-consumer-id&gt;&quot; \\\n  &quot;https://www.metamuseum.org/api/activity?limit=100&amp;type=Create&quot;\n\ncurl -H &quot;Accept: application/activity+json&quot; \\\n  -H &quot;x-linked-art-consumer-id: &lt;your-stable-consumer-id&gt;&quot; \\\n  &quot;https://www.metamuseum.org/api/activity?limit=100&amp;type=Update&quot;\n\ncurl -H &quot;Accept: application/activity+json&quot; \\\n  -H &quot;x-linked-art-consumer-id: &lt;your-stable-consumer-id&gt;&quot; \\\n  &quot;https://www.metamuseum.org/api/activity?limit=100&amp;type=Delete&quot;\n\nUse an ID owned by your system, not a test or demo ID. We will verify it appears as a declared external consumer. If `Update` or `Delete` returns zero items, report that explicitly; strict coverage waits until real update or tombstone rows exist in the public feed.\n</code></pre>\n<p>Verify all three IDs:</p>\n<pre><code>\npnpm activity:adoption:matrix -- --base-url https://www.metamuseum.org --consumer-id &lt;id-1&gt; --consumer-id &lt;id-2&gt; --consumer-id &lt;id-3&gt;\n</code></pre>\n<p>If the public feed still lacks `Update` or `Delete` rows, create only real</p>\n<p>source events before asking partners to re-read them. A reviewed existing-record</p>\n<p>metadata correction emits `Update`; a confirmed upstream `404`/`410` tombstone</p>\n<p>can be recorded with:</p>\n<pre><code>\npnpm activity:tombstone:evidence -- --object-id &lt;canonical-record-uri&gt; --provider &lt;provider-key&gt; --upstream-status 410 --observed-at &lt;ISO timestamp&gt; --evidence-ref artifacts/activity-syndication/&lt;real-upstream-404-or-410-proof&gt;.json\n</code></pre>\n<h2 id=\"durable-subscription-ask\">Durable Subscription Ask</h2>\n<p>After the same consumers are observed, ask each to register a callback:</p>\n<pre><code>\ncurl -X POST &quot;https://www.metamuseum.org/api/activity/subscriptions&quot; \\\n  -H &quot;content-type: application/json&quot; \\\n  -H &quot;accept: application/activity+json&quot; \\\n  -H &quot;x-linked-art-consumer-id: &lt;your-stable-consumer-id&gt;&quot; \\\n  --data &#39;{\n    &quot;callbackUrl&quot;: &quot;https://&lt;public-consumer-host&gt;/&lt;activity-callback-path&gt;&quot;,\n    &quot;eventTypes&quot;: [&quot;Create&quot;, &quot;Update&quot;, &quot;Delete&quot;]\n  }&#39;\n</code></pre>\n<p>Then attach recent callback verification evidence to the subscription ledger with a public callback host, 2xx `statusCode`, `verifiedAt`, and a real `evidenceRef`. Recheck:</p>\n<pre><code>\npnpm activity:subscription:verify -- --consumer-id &lt;your-stable-consumer-id&gt; --callback-url https://&lt;public-consumer-host&gt;/&lt;activity-callback-path&gt; --status-code 204 --verified-at &lt;ISO timestamp&gt; --evidence-ref artifacts/activity-syndication/&lt;real-callback-proof&gt;.json\npnpm activity:syndication:evidence\npnpm activity:syndication:check\npnpm era-c:exit-gate:public\n</code></pre>\n<p>The durable gate passes only when the same three declared external consumer IDs have observed feed-read telemetry covering `Create`, `Update`, and `Delete`, active HTTPS subscriptions covering those same event types, and recent 2xx callback verification evidence.</p>\n<p>MetaHistoryBook&#39;s verified callback row:</p>\n<pre><code>\ncurl -X POST &quot;https://www.metamuseum.org/api/activity/subscriptions&quot; \\\n  -H &quot;content-type: application/json&quot; \\\n  -H &quot;accept: application/activity+json&quot; \\\n  -H &quot;x-linked-art-consumer-id: metahistorybook-harvester-prod&quot; \\\n  --data &#39;{\n    &quot;callbackUrl&quot;: &quot;https://www.metahistorybook.com/api/metamuseum/callback&quot;,\n    &quot;eventTypes&quot;: [&quot;Create&quot;, &quot;Update&quot;, &quot;Delete&quot;],\n    &quot;signingRequired&quot;: true,\n    &quot;signingSecretRef&quot;: &quot;metahistorybook-harvester-prod-v1&quot;\n  }&#39;\n</code></pre>\n<p>MetaMuseum rechecked liveness, sent one signed production `Create` Activity</p>\n<p>payload, and received `204` from that callback at</p>\n<p>`2026-07-05T17:13:13.312Z`. The proof artifact intentionally omits the HMAC</p>\n<p>secret and signature value:</p>\n<pre><code>\npnpm activity:subscription:verify -- --consumer-id metahistorybook-harvester-prod --callback-url https://www.metahistorybook.com/api/metamuseum/callback --status-code 204 --verified-at 2026-07-05T17:13:13.312Z --evidence-ref artifacts/activity-syndication/metahistorybook-harvester-prod-callback-2026-07-05T17-13-13-312Z.json\n</code></pre>\n<p>Their 2026-07-05T16:37Z typed read reported `Create: 108`, `Update: 0`, and</p>\n<p>`Delete: 0`; the explicit zeroes should remain filed as honest partner feedback,</p>\n<p>not as complete activity-type coverage.</p>\n<h2 id=\"reliability-evidence\">Reliability Evidence</h2>\n<p>Nightly `.github/workflows/era-c-exit-gate-evidence.yml` now commits compact rolling evidence inputs back to `main`, including the k6 trend and public uptime history. Keep these repository variables configured:</p>\n<ul><li>`METAMUSEUM_EVIDENCE_BASE_URL=https://www.metamuseum.org`</li><li>`METAMUSEUM_PUBLIC_READ_BASE_URL=https://www.metamuseum.org`</li><li>`METAMUSEUM_EVIDENCE_IIIF_TILE_URL=&lt;public tile/static image URL&gt;`</li><li>`METAMUSEUM_ACTIVITY_CONSUMER_IDS=&lt;id-1&gt;,&lt;id-2&gt;,&lt;id-3&gt;` after real consumers exist</li></ul>\n<p>Daily review:</p>\n<pre><code>\npnpm longterm:evidence:public\npnpm review:goals:local\n</code></pre>\n<p>`pnpm longterm:evidence:public` also runs the daily maintenance companion for</p>\n<p>the runway. It identifies failed SLO samples, failed public-read probe paths,</p>\n<p>passing distinct evidence days, the earliest failure-free window date, and the</p>\n<p>real ActivityStreams consumers still needed; it does not mutate the evidence</p>\n<p>history. Use the generated `acceptanceRows` as the 30-day reliability ledger:</p>\n<p>SLO sample depth, SLO failure-free window, uptime observation depth, uptime</p>\n<p>availability, ActivityStreams consumer depth, activity-type coverage, and strict</p>\n<p>long-term packet refresh must all be `ready` before this lane can support a</p>\n<p>strict production-readiness claim.</p>","updatedAt":"2018-10-20T01:46:40.000Z","checksum":"4d89c9ef04107618baaab40947277e8dcf79bd6e0de619a3384a87cc9f17724a","checksumPrefix":"4d89c9ef0410","anchorCount":6,"lineCount":246,"rawUrl":"/api/docs/content?path=ops%2Fexternal-evidence-request-pack.md","htmlUrl":"/docs?doc=ops%2Fexternal-evidence-request-pack.md","apiUrl":"/api/docs/content?path=ops%2Fexternal-evidence-request-pack.md"}