{
 "_meta": {
  "head": "2f1dbc36c7fa77aeb721e34a838d12f26aefd0d8",
  "commit_date": "2026-07-10",
  "audit_date": "2026-07-29",
  "method": "read-only static analysis, six parallel platform sweeps + lead-auditor reconciliation; no builds, no vendor writes, no commits",
  "scoring_rulings": [
   "G6 = 0 for ALL capabilities: no live vendor-2xx proof exists (verify:live harness never run per UNVERIFIED_INVENTORY.md; pre-activation-verification.md is read-only; 354 mock boundaries; zero no-mock sandbox tests).",
   "G3 = write scope REQUESTED (via the platform's consent model) + PERSISTED on the connection + refresh-preserved. Pre-flight ENFORCEMENT at the writer boundary is a blast-radius FINDING, not a gate failure.",
   "RECONCILIATION: the Meta sweep failed G3 (capping 24 verbs at G2) for 'ads_management not enforced at boundary'; the Google sweep passed G3 (G5) despite NO write-path readback at all. Inconsistent. Lead auditor applied G3 uniformly -> Meta ad/create/audience verbs lifted G2->G5 (video upload->G4 for an independent contract defect). TikTok lifted G2->G4 (BC-config scope carried+persisted; the '1'-sentinel rubber-stamp readback is recorded as a scope-drift finding, not a G3 fail).",
   "Shadow-default returns an explicit {shadow:true} envelope + logs CRITICAL + stamps executionMode='shadow' -> transparent, not a fabricated success -> does NOT fail the G5 dry-run clause; it is the reason G6=0.",
   "weights: Tier1=3, Tier2=2, Tier3=1"
  ],
  "scores": {
   "overall": {
    "strict_G6": 0.0,
    "plausible_G4plus": 0.5656,
    "maturity": 0.4522,
    "histogram": {
     "G0": 63,
     "G1": 2,
     "G2": 0,
     "G3": 1,
     "G4": 17,
     "G5": 47,
     "G6": 0
    },
    "n": 130,
    "total_weight": 244
   },
   "tier1_only": {
    "strict_G6": 0,
    "plausible_G4plus": 0.688,
    "maturity": 0.552,
    "histogram": {
     "G0": 9,
     "G1": 1,
     "G4": 5,
     "G5": 17
    }
   },
   "business_day_weighted": {
    "strict_G6": 0,
    "plausible_G4plus": 0.58,
    "maturity": 0.468,
    "weights": {
     "meta": 0.4,
     "google": 0.25,
     "shopify": 0.1,
     "klaviyo": 0.1,
     "ga4": 0.1,
     "tiktok": 0.05
    }
   },
   "per_platform": {
    "meta": {
     "strict_G6": 0,
     "plausible_G4plus": 0.737,
     "maturity": 0.592,
     "tier1_plausible": 0.7,
     "histogram": {
      "G0": 13,
      "G4": 5,
      "G5": 24
     }
    },
    "google": {
     "strict_G6": 0,
     "plausible_G4plus": 0.617,
     "maturity": 0.517,
     "tier1_plausible": 0.75,
     "histogram": {
      "G0": 12,
      "G1": 2,
      "G4": 2,
      "G5": 15
     }
    },
    "shopify": {
     "strict_G6": 0,
     "plausible_G4plus": 0.457,
     "maturity": 0.381,
     "tier1_plausible": 0.8,
     "histogram": {
      "G0": 12,
      "G5": 6
     }
    },
    "klaviyo": {
     "strict_G6": 0,
     "plausible_G4plus": 0.154,
     "maturity": 0.167,
     "tier1_plausible": 0,
     "histogram": {
      "G0": 11,
      "G3": 1,
      "G5": 2
     }
    },
    "tiktok": {
     "strict_G6": 0,
     "plausible_G4plus": 0.708,
     "maturity": 0.472,
     "tier1_plausible": 1,
     "histogram": {
      "G0": 6,
      "G4": 7
     }
    },
    "ga4": {
     "strict_G6": 0,
     "plausible_G4plus": 0.348,
     "maturity": 0.232,
     "tier1_plausible": 0.667,
     "histogram": {
      "G0": 9,
      "G4": 3
     }
    }
   },
   "as_of": "2026-07-29",
   "basis": "audit_gate where present, else gate",
   "note": "The audit as run. Reproduces compute.mjs and every figure in CRV-2026-001 section 1: 130 capabilities, total weight 244, 0.0% strict, 56.6% plausible, 45.2% maturity."
  },
  "raw_evidence_files": [
   "EVIDENCE-meta.md",
   "EVIDENCE-google.md",
   "EVIDENCE-shopify.md",
   "EVIDENCE-klaviyo.md",
   "EVIDENCE-tiktok.md",
   "EVIDENCE-ga4.md"
  ],
  "note": "Full per-capability greps and traces live in the EVIDENCE-<platform>.md files. Rows below carry the decisive gate citations; api_version/vendor_endpoint/scopes/proof are per-row. proof_type='none' everywhere.",
  "addendum": {
   "date": "2026-07-29",
   "reason": "Production found live: META_WRITE_MODE set in prod (vercel env ls, 36d ago, w/ ACTIONS_ENABLED). Other 4 WRITE_MODE vars absent -> shadow (VERIFIED).",
   "strict_now": {
    "meta": "UNKNOWN_PENDING_TELEMETRY (was 0.0% on false shadow-assumption; META live-configured in prod)",
    "google_shopify_klaviyo_tiktok_ga4": "0.0% VERIFIED (WRITE_MODE absent -> shadow)"
   },
   "correction_a_staleness_applied": {
    "rows_capped_G5_to_G4": 8,
    "effect": "Plausible unchanged (G4 still plausible); Maturity drops. Shopify Maturity 38.1->32.3%, overall 45.6->44.2%."
   },
   "correction_b_enforcement_sensitivity": {
    "definition": "G3 requires the writer to REFUSE a mis-scoped connection pre-flight (not merely request the scope). Relevant now that prod is live and stale-scoped connections fail for real.",
    "plausible_overall": "57.0% -> 5.4%",
    "plausible_tier1": "68.8% -> 6.3%",
    "per_platform": {
     "meta": "73.7->1.3%",
     "google": "61.7->0.0%",
     "shopify": "48.5->0.0%",
     "tiktok": "70.8->0.0%",
     "ga4": "34.8% (unchanged, fail-closed)",
     "klaviyo": "15.4% (keyed)"
    },
    "note": "Not applied to individual row gates (it is a sensitivity view); computed in compute-v2. The Meta 73.7->1.3 gap IS the ads_management-non-enforcement finding, now a live exposure."
   },
   "telemetry_pending": {
    "instructions": "From prod ActionAudit executionMode='live': success -> gate:6/proof_type:telemetry/last_success_at/count; executions-but-zero-success -> gate:5 live_failing:true + error class. Then recompute all scores.",
    "meta_gate6_rows": null,
    "meta_live_failing_rows": null,
    "last_success_at": null
   },
   "stale_findings_corrected": {
    "date": "2026-07-29",
    "by": "write-program Prompt 1/2",
    "GAPS_D2_and_CONTAINMENT_C1": "STALE/RESOLVED — cumulative DOLLAR cap ($500 default), fail-CLOSED reads, and cron reserveAutoFireSpend routing ALL already shipped in Road-to-100% Prompt 1 (A2). Evidence: lib/executor/guardrailEvaluator.ts:186/233/276, lib/guardrails/constants.ts:26, lib/actions/executeVerb.ts:1114, lib/executor/processGoal.ts:339, lib/divergence-response/adapter.ts:210. The audit relied on the stale pre-activation-verification.md CHECK 3. See GAPS.md D2 (RESOLVED banner) + SPRINT-1.md.",
    "note": "Findings retained (not deleted) with correcting file:line per the sprint rule."
   },
   "prompt2_changes": {
    "date": "2026-07-29",
    "changed": [
     "meta:video upload -> G5",
     "klaviyo:campaign send/schedule -> G4"
    ],
    "note": "Klaviyo send/schedule G3->G4, Meta video G4->G5 (contract defects doc-verified fixed); Shopify api_version 2024-01->2026-07. No capability reached G6 (nothing proven this sprint)."
   },
   "sprint2b": {
    "date": "2026-07-30",
    "built": "27 doc-verified writers across 6 platforms (Meta 3, Google 6 verbs, Shopify 1+GraphQL path, Klaviyo 5, TikTok 6, GA4 6). All Tier-1 capabilities now BUILT.",
    "status": "built + unit-tested + doc-verified + WriterContract-registered (CI-invariant green). NOT yet wired into executeVerb/tool-registry/reversibility -> not yet G2-reachable as capabilities; reachability wiring staged (snippets in agent transcripts). G6=0 (no vendor call, nothing proven).",
    "bugs_found": "Google customer-match cast uses wrong SDK method names (would throw live) — lead to fix source+test. GA4 Audience.description required-but-unset (would 400 live) — FIXED.",
    "blocked": "TikTok custom-audience file upload (multipart transport), TikTok full DPA ad wiring, GA4 app streams + RestrictedMetricType enum + MP secret store.",
    "see": "audit/write-program/SPRINT-2B.md"
   },
   "sprint2c": {
    "date": "2026-07-30",
    "reachability": "All 27 Sprint-2B writers wired G1->G2+ (barrel + PLATFORM_BY_VERB + executeVerb register + reversibility + tool-registry). Route through prepare* (scope preflight + *_WRITE_MODE). Propose-only. Taxonomy + CI-contract invariants green.",
    "gates_now": "Meta 3 / Google 5 / Shopify 1 = G5; Klaviyo 5 = G4-G5; TikTok 6 = G4; GA4 6 = G4-G5. G6=0 (shadow, unproven).",
    "bug1_fixed": "google-customer-match SDK method names create/addOperations/run -> createOfflineUserDataJob/addOfflineUserDataJobOperations/runOfflineUserDataJob (would throw live). Test rewritten to assert the SDK contract via a Proxy that throws on guessed names.",
    "shopify_rest": "VERIFIED present on 2026-07 (products/variants/collects PUT/POST/DELETE) — deprecated not removed. No migration/revert needed.",
    "task4": "Test-quality sweep: pixel-writers.test.ts + sprint-8-meta-create-verbs.test.ts are implementation-mirroring (mock returns ok regardless of endpoint -> CANNOT catch an invented endpoint, same class as bug #1). Rewrite recommended. Full table in SPRINT-2C.md.",
    "sam_grant": "Sam tiktok_* wildcard auto-granted the 6 new TikTok verbs (98->104), all propose-only.",
    "see": "audit/write-program/SPRINT-2C.md"
   },
   "sprint3": {
    "date": "2026-07-30",
    "task1": "Meta writer tests (pixel-writers, capi-send, sprint-8-meta-create, meta.test) made CONTRACT-asserting vs fetched docs (/adspixels, /events, /campaigns|adsets|ads, node POST). Contract-shaped metaFetch mock throws on wrong endpoint. PROVEN: deliberate endpoint changes now fail (were green).",
    "task2": "Persona wildcard audit: ONLY tiktok_* (Sam + Cresva) resolves to write verbs = 20 TikTok verbs, 12 reversible:none incl tiktok_send_server_event. All propose-only. Recommend explicit grants (prevents the 2C silent auto-grant creep); not applied (trust decision).",
    "task3": "Live-verify harness: safety test verb-agnostic + still refuses (15 green). arm/seed are brand-level (no per-verb change). Added 10 scenarios + 5 prereq env checks. Dry preflight = 22 blockers (no vendor call). Harness-blocked verbs listed (tiktok multipart audience, ga4 MP secret, etc.).",
    "task4": "Sweep extended: schema/validator/invariant tests are correctly-scoped (SCHEMA-CONTRACT pins real enums; UNIT-CONTRACT pins micros/cents). No new bug-#1 MIRROR. Mild gap: sprint-11-shopify/klaviyo behavioral tests dont assert endpoints for verbs unique to them (low risk, shadow).",
    "gate": "G6=0. Nothing armed, no vendor called. Per-platform preflight (what each needs before arming) in SPRINT-3.md.",
    "see": "audit/write-program/SPRINT-3.md"
   },
   "sprint2e": {
    "date": "2026-07-30",
    "task1": "Meta scope readback FIXED — granted scopes were in metadata.grantedScopes (string) not the empty grantedScopes[] column, so META_WRITE_MODE=live refused every write. resolveGrantedScopes reads array->metadata.grantedScopes->metadata.scope->scope; callback writes the column canonically; backfill script for the 8 rows. Write-scoped passes, read-only refuses (tested).",
    "task2": "Brand-account BINDING at writer boundary (replaced the reverted static-allowlist idea — those accounts are customer-owned). resolveMetaAdAccountBindingRefusal refuses fail-closed if brand has no AdAccount row (the 23-Jun Cresva defect) or requested account != linked externalId. Before any vendor call. Tested (4).",
    "task3": "markExecuted now DERIVES vendorOk/vendorStatusCode/scopeVerified on every path (divergence/processGoal/rollback no longer leave them null). Backfill script grades historical rows; {success:true}-no-id rows left null (ungradeable). Every executed row gradeable going forward.",
    "gate": "Live Meta path now unblocked (scope readback) AND gated (binding + scope preflight + spend guardrail). G6=0, nothing armed, no vendor called.",
    "see": "audit/write-program/SPRINT-2E.md"
   }
  },
  "scores_post_fix": {
   "as_of": "2026-09-05",
   "basis": "gate",
   "overall": {
    "n": 130,
    "total_weight": 244,
    "strict_G6": 0.0,
    "plausible_G4plus": 0.5656,
    "maturity": 0.4399,
    "histogram": {
     "G0": 63,
     "G1": 2,
     "G2": 0,
     "G3": 1,
     "G4": 24,
     "G5": 40,
     "G6": 0
    }
   },
   "note": "THE SPRINT MADE THE MEASUREMENT STRICTER AND LEFT THE HEADLINE WHERE IT WAS. Plausible is unchanged from the audit at 56.6%. The sprint's only Plausible gain was the klaviyo campaign send/schedule promotion, and that was withdrawn on 2026-09-05 on the row's own evidence. Maturity falls from 45.2% to 44.0%, because six Shopify capabilities were correctly demoted from G5 to G4 by the contract review. A number going down because the measurement improved is the result, not a regression to explain."
  }
 },
 "capabilities": [
  {
   "platform": "meta",
   "capability": "campaign budget update",
   "tier": 1,
   "weight": 3,
   "gate": 5,
   "failing_gate": "G6",
   "vendor_endpoint": "POST https://graph.facebook.com/v21.0/{campaignId}",
   "api_version": "v21.0",
   "scopes_required": "ads_management",
   "scopes_requested": "ads_read,business_management,ads_management,catalog_management",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 1,
     "file": "lib/ads/writers/meta.ts",
     "line": 316,
     "snippet": "metaFetch(metaUrl(campaignId),{method:POST,body:{daily_budget:String(cents)}})"
    },
    {
     "gate": 2,
     "file": "lib/actions/executeVerb.ts",
     "line": 452,
     "snippet": "register(shift_budget, setCampaignBudgetAdapter)"
    }
   ],
   "notes": "minor-units correct. ads_management requested+persisted(grantedScopes) => G3 pass (RECONCILED from sweep G2). Not enforced at writer boundary => blast-radius finding. G6=0 shadow default."
  },
  {
   "platform": "meta",
   "capability": "ad set budget update",
   "tier": 1,
   "weight": 3,
   "gate": 5,
   "failing_gate": "G6",
   "vendor_endpoint": "POST https://graph.facebook.com/v21.0/{adSetId}",
   "api_version": "v21.0",
   "scopes_required": "ads_management",
   "scopes_requested": "ads_read,business_management,ads_management,catalog_management",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 1,
     "file": "lib/ads/writers/meta.ts",
     "line": 746,
     "snippet": "POST /{adSetId} {daily_budget}"
    },
    {
     "gate": 2,
     "file": "lib/actions/executeVerb.ts",
     "line": 515,
     "snippet": "register(shift_adset_budget)"
    }
   ],
   "notes": "RECONCILED G2->G5."
  },
  {
   "platform": "meta",
   "capability": "campaign status (active/pause)",
   "tier": 1,
   "weight": 3,
   "gate": 5,
   "failing_gate": "G6",
   "vendor_endpoint": "POST https://graph.facebook.com/v21.0/{campaignId}",
   "api_version": "v21.0",
   "scopes_required": "ads_management",
   "scopes_requested": "ads_read,business_management,ads_management,catalog_management",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 1,
     "file": "lib/ads/writers/meta.ts",
     "line": 149,
     "snippet": "POST {status:PAUSED}; resume:217"
    },
    {
     "gate": 5,
     "file": "lib/ads/writers/meta.ts",
     "line": 135,
     "snippet": "preState via GET for reversal"
    }
   ],
   "notes": "reversible pair. RECONCILED G2->G5."
  },
  {
   "platform": "meta",
   "capability": "ad set status",
   "tier": 1,
   "weight": 3,
   "gate": 5,
   "failing_gate": "G6",
   "vendor_endpoint": "POST https://graph.facebook.com/v21.0/{adSetId}",
   "api_version": "v21.0",
   "scopes_required": "ads_management",
   "scopes_requested": "...,ads_management,...",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 1,
     "file": "lib/ads/writers/meta.ts",
     "line": 571,
     "snippet": "pauseAdSet; resumeAdSet:645"
    }
   ],
   "notes": "RECONCILED G2->G5."
  },
  {
   "platform": "meta",
   "capability": "ad status",
   "tier": 1,
   "weight": 3,
   "gate": 5,
   "failing_gate": "G6",
   "vendor_endpoint": "POST https://graph.facebook.com/v21.0/{adId}",
   "api_version": "v21.0",
   "scopes_required": "ads_management",
   "scopes_requested": "...,ads_management,...",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 1,
     "file": "lib/ads/writers/meta.ts",
     "line": 381,
     "snippet": "pauseAd; resumeAd:437; archiveAd:510"
    }
   ],
   "notes": "idempotent already-ARCHIVED no-op. RECONCILED G2->G5."
  },
  {
   "platform": "meta",
   "capability": "bid strategy change",
   "tier": 1,
   "weight": 3,
   "gate": 5,
   "failing_gate": "G6",
   "vendor_endpoint": "POST https://graph.facebook.com/v21.0/{adsetId}",
   "api_version": "v21.0",
   "scopes_required": "ads_management",
   "scopes_requested": "...,ads_management,...",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 1,
     "file": "lib/ads/writers/meta.ts",
     "line": 1286,
     "snippet": "changeAdSetBidStrategy POST {bid_strategy}"
    }
   ],
   "notes": "captures old bid for reversal. RECONCILED G2->G5."
  },
  {
   "platform": "meta",
   "capability": "bid cap / cost cap set",
   "tier": 1,
   "weight": 3,
   "gate": 5,
   "failing_gate": "G6",
   "vendor_endpoint": "POST https://graph.facebook.com/v21.0/{adsetId}",
   "api_version": "v21.0",
   "scopes_required": "ads_management",
   "scopes_requested": "...,ads_management,...",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 1,
     "file": "lib/ads/writers/meta.ts",
     "line": 1278,
     "snippet": "bid_amount=String(cents); roas_average_floor=round(x*10000)"
    }
   ],
   "notes": "minor-units + ROAS x10000 correct. RECONCILED G2->G5."
  },
  {
   "platform": "meta",
   "capability": "CBO toggle",
   "tier": 1,
   "weight": 3,
   "gate": 0,
   "failing_gate": "G1",
   "vendor_endpoint": null,
   "api_version": null,
   "scopes_required": "ads_management",
   "scopes_requested": "...,ads_management,...",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 0,
     "file": "lib/ads/writers/meta.ts",
     "line": 0,
     "snippet": "no campaign_budget_optimization enable/disable writer"
    }
   ],
   "notes": "NOT IMPLEMENTED."
  },
  {
   "platform": "meta",
   "capability": "schedule / dayparting change",
   "tier": 1,
   "weight": 3,
   "gate": 0,
   "failing_gate": "G1",
   "vendor_endpoint": null,
   "api_version": null,
   "scopes_required": "ads_management",
   "scopes_requested": "...,ads_management,...",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 0,
     "file": "lib/ads/writers/meta-create-schemas.ts",
     "line": 146,
     "snippet": "start_time only at create; no adset_schedule/pacing_type writer"
    }
   ],
   "notes": "NOT IMPLEMENTED as a mutation."
  },
  {
   "platform": "meta",
   "capability": "spend cap set",
   "tier": 1,
   "weight": 3,
   "gate": 0,
   "failing_gate": "G1",
   "vendor_endpoint": null,
   "api_version": null,
   "scopes_required": "ads_management",
   "scopes_requested": "...,ads_management,...",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 0,
     "file": "lib/ads/writers/meta.ts",
     "line": 0,
     "snippet": "no spend_cap writer; daily_budget != spend_cap"
    }
   ],
   "notes": "NOT IMPLEMENTED."
  },
  {
   "platform": "meta",
   "capability": "campaign create",
   "tier": 2,
   "weight": 2,
   "gate": 5,
   "failing_gate": "G6",
   "vendor_endpoint": "POST https://graph.facebook.com/v21.0/act_{id}/campaigns",
   "api_version": "v21.0",
   "scopes_required": "ads_management",
   "scopes_requested": "...,ads_management,...",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 1,
     "file": "lib/ads/writers/meta.ts",
     "line": 892,
     "snippet": "POST /campaigns status PAUSED"
    },
    {
     "gate": 5,
     "file": "lib/ads/writers/meta.ts",
     "line": 819,
     "snippet": "assertPausedInvariant + findPriorCreate idempotency"
    }
   ],
   "notes": "forced PAUSED 3 ways. RECONCILED G2->G5."
  },
  {
   "platform": "meta",
   "capability": "ad set create",
   "tier": 2,
   "weight": 2,
   "gate": 5,
   "failing_gate": "G6",
   "vendor_endpoint": "POST https://graph.facebook.com/v21.0/act_{id}/adsets",
   "api_version": "v21.0",
   "scopes_required": "ads_management",
   "scopes_requested": "...,ads_management,...",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 1,
     "file": "lib/ads/writers/meta.ts",
     "line": 987,
     "snippet": "POST /adsets targeting/promoted_object PAUSED"
    }
   ],
   "notes": "OFFSITE_CONVERSIONS needs pixel (honest fail). RECONCILED G2->G5."
  },
  {
   "platform": "meta",
   "capability": "ad create",
   "tier": 2,
   "weight": 2,
   "gate": 5,
   "failing_gate": "G6",
   "vendor_endpoint": "POST https://graph.facebook.com/v21.0/act_{id}/ads",
   "api_version": "v21.0",
   "scopes_required": "ads_management",
   "scopes_requested": "...,ads_management,...",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 1,
     "file": "lib/ads/writers/meta.ts",
     "line": 1013,
     "snippet": "POST /ads {adset_id,creative,PAUSED}"
    }
   ],
   "notes": "RECONCILED G2->G5."
  },
  {
   "platform": "meta",
   "capability": "targeting edit",
   "tier": 2,
   "weight": 2,
   "gate": 5,
   "failing_gate": "G6",
   "vendor_endpoint": "POST https://graph.facebook.com/v21.0/{adsetId}",
   "api_version": "v21.0",
   "scopes_required": "ads_management",
   "scopes_requested": "...,ads_management,...",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 1,
     "file": "lib/ads/writers/meta.ts",
     "line": 1230,
     "snippet": "POST {targeting}; old GET first (1219)"
    }
   ],
   "notes": "full REPLACE not merge. RECONCILED G2->G5."
  },
  {
   "platform": "meta",
   "capability": "placement edit",
   "tier": 2,
   "weight": 2,
   "gate": 4,
   "failing_gate": "G5",
   "vendor_endpoint": "POST https://graph.facebook.com/v21.0/{adsetId}",
   "api_version": "v21.0",
   "scopes_required": "ads_management",
   "scopes_requested": "...,ads_management,...",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 1,
     "file": "lib/ads/writers/meta.ts",
     "line": 919,
     "snippet": "placement merged into targeting; edit via full targeting replace only"
    }
   ],
   "notes": "CREATE-TIME / full-replace only — no dedicated placement patch => capped G4 (partial capability)."
  },
  {
   "platform": "meta",
   "capability": "optimization goal / conversion event change",
   "tier": 2,
   "weight": 2,
   "gate": 4,
   "failing_gate": "G5",
   "vendor_endpoint": "POST https://graph.facebook.com/v21.0/act_{id}/adsets",
   "api_version": "v21.0",
   "scopes_required": "ads_management",
   "scopes_requested": "...,ads_management,...",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 1,
     "file": "lib/ads/writers/meta.ts",
     "line": 934,
     "snippet": "createAdSet optimization_goal + promoted_object.custom_event_type"
    }
   ],
   "notes": "CREATE-TIME ONLY; no change-on-existing writer => capped G4."
  },
  {
   "platform": "meta",
   "capability": "attribution setting",
   "tier": 2,
   "weight": 2,
   "gate": 4,
   "failing_gate": "G5",
   "vendor_endpoint": "POST https://graph.facebook.com/v21.0/act_{id}/adsets",
   "api_version": "v21.0",
   "scopes_required": "ads_management",
   "scopes_requested": "...,ads_management,...",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 1,
     "file": "lib/ads/writers/meta.ts",
     "line": 946,
     "snippet": "attribution_spec at create only"
    }
   ],
   "notes": "CREATE-TIME ONLY => capped G4."
  },
  {
   "platform": "meta",
   "capability": "creative image upload",
   "tier": 2,
   "weight": 2,
   "gate": 5,
   "failing_gate": "G6",
   "vendor_endpoint": "POST https://graph.facebook.com/v21.0/act_{id}/adimages",
   "api_version": "v21.0",
   "scopes_required": "ads_management",
   "scopes_requested": "...,ads_management,...",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 1,
     "file": "lib/ads/writers/meta.ts",
     "line": 1082,
     "snippet": "POST /adimages {bytes:base64} -> image_hash"
    }
   ],
   "notes": "RECONCILED G2->G5."
  },
  {
   "platform": "meta",
   "capability": "video upload",
   "tier": 2,
   "weight": 2,
   "gate": 5,
   "failing_gate": "G6",
   "vendor_endpoint": "POST https://graph.facebook.com/v21.0/act_{id}/advideos",
   "api_version": "v21.0",
   "scopes_required": "ads_management",
   "scopes_requested": "...,ads_management,...",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 4,
     "file": "lib/ads/writers/meta.ts",
     "line": 1426,
     "snippet": "CONTRACT DEFECT: base64-in-JSON vs Meta multipart video_file_chunk (self-documented, unverified)"
    }
   ],
   "notes": "[Prompt 2 CONTRACT FIX] switched base64 video_file_chunk -> doc-verified file_url; the G4 contract defect is resolved -> G5 (fully built, unproven). independent G4 contract defect (kept below G5).",
   "audit_gate": 4,
   "revised": {
    "sprint": "Prompt 2 contract fix",
    "from": 4,
    "to": 5,
    "status": "stands",
    "why": "base64 video_file_chunk replaced with the doc-verified file_url; the G4 contract defect is resolved."
   }
  },
  {
   "platform": "meta",
   "capability": "thumbnail",
   "tier": 2,
   "weight": 2,
   "gate": 0,
   "failing_gate": "G1",
   "vendor_endpoint": null,
   "api_version": null,
   "scopes_required": "ads_management",
   "scopes_requested": "...,ads_management,...",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 0,
     "file": "lib/ads/writers/meta.ts",
     "line": 1532,
     "snippet": "image_url is a field in video creative, not a mutation"
    }
   ],
   "notes": "NOT a distinct capability."
  },
  {
   "platform": "meta",
   "capability": "ad creative create",
   "tier": 2,
   "weight": 2,
   "gate": 5,
   "failing_gate": "G6",
   "vendor_endpoint": "POST https://graph.facebook.com/v21.0/act_{id}/adcreatives",
   "api_version": "v21.0",
   "scopes_required": "ads_management",
   "scopes_requested": "...,ads_management,...",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 1,
     "file": "lib/ads/writers/meta.ts",
     "line": 1565,
     "snippet": "createCreative POST /adcreatives object_story_spec"
    }
   ],
   "notes": "single_image/video/catalog/carousel. RECONCILED G2->G5."
  },
  {
   "platform": "meta",
   "capability": "asset feed / dynamic creative",
   "tier": 2,
   "weight": 2,
   "gate": 4,
   "failing_gate": "G5",
   "vendor_endpoint": "POST https://graph.facebook.com/v21.0/act_{id}/adcreatives",
   "api_version": "v21.0",
   "scopes_required": "ads_management",
   "scopes_requested": "...,ads_management,...",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 1,
     "file": "lib/ads/writers/meta.ts",
     "line": 1533,
     "snippet": "catalog/carousel only; NO asset_feed_spec true dynamic creative"
    }
   ],
   "notes": "partial coverage => capped G4."
  },
  {
   "platform": "meta",
   "capability": "duplicate campaign / ad set",
   "tier": 2,
   "weight": 2,
   "gate": 5,
   "failing_gate": "G6",
   "vendor_endpoint": "POST https://graph.facebook.com/v21.0/{id}/copies",
   "api_version": "v21.0",
   "scopes_required": "ads_management",
   "scopes_requested": "...,ads_management,...",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 1,
     "file": "lib/ads/writers/meta.ts",
     "line": 1332,
     "snippet": "POST /copies {deep_copy,status_option:PAUSED}"
    }
   ],
   "notes": "RECONCILED G2->G5."
  },
  {
   "platform": "meta",
   "capability": "Advantage+ shopping (ASC) create",
   "tier": 2,
   "weight": 2,
   "gate": 5,
   "failing_gate": "G6",
   "vendor_endpoint": "POST https://graph.facebook.com/v21.0/act_{id}/campaigns",
   "api_version": "v21.0",
   "scopes_required": "ads_management",
   "scopes_requested": "...,ads_management,...",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 1,
     "file": "lib/ads/writers/meta.ts",
     "line": 2080,
     "snippet": "smart_promotion_type:AUTOMATED_SHOPPING_ADS PAUSED"
    }
   ],
   "notes": "structural refusal reported precisely. RECONCILED G2->G5."
  },
  {
   "platform": "meta",
   "capability": "custom audience create/update/delete",
   "tier": 3,
   "weight": 1,
   "gate": 5,
   "failing_gate": "G6",
   "vendor_endpoint": "POST/DELETE https://graph.facebook.com/v21.0/act_{id}/customaudiences",
   "api_version": "v21.0",
   "scopes_required": "ads_management",
   "scopes_requested": "...,ads_management,...",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 1,
     "file": "lib/ads/writers/meta.ts",
     "line": 1690,
     "snippet": "WEBSITE/ENGAGEMENT/SAVED create; DELETE:1860"
    }
   ],
   "notes": "no membership-update beyond re-create. RECONCILED G2->G5."
  },
  {
   "platform": "meta",
   "capability": "customer list upload w/ hashing",
   "tier": 3,
   "weight": 1,
   "gate": 5,
   "failing_gate": "G6",
   "vendor_endpoint": "POST https://graph.facebook.com/v21.0/{audienceId}/users",
   "api_version": "v21.0",
   "scopes_required": "ads_management",
   "scopes_requested": "...,ads_management,...",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 5,
     "file": "lib/ads/writers/meta.ts",
     "line": 1762,
     "snippet": "SHA256 at execution; raw PII never persisted/logged; batches 5000"
    }
   ],
   "notes": "zero-PII. RECONCILED G2->G5."
  },
  {
   "platform": "meta",
   "capability": "lookalike create",
   "tier": 3,
   "weight": 1,
   "gate": 5,
   "failing_gate": "G6",
   "vendor_endpoint": "POST https://graph.facebook.com/v21.0/act_{id}/customaudiences",
   "api_version": "v21.0",
   "scopes_required": "ads_management",
   "scopes_requested": "...,ads_management,...",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 1,
     "file": "lib/ads/writers/meta.ts",
     "line": 1817,
     "snippet": "subtype LOOKALIKE lookalike_spec"
    }
   ],
   "notes": "RECONCILED G2->G5."
  },
  {
   "platform": "meta",
   "capability": "audience share across accounts",
   "tier": 3,
   "weight": 1,
   "gate": 0,
   "failing_gate": "G1",
   "vendor_endpoint": null,
   "api_version": null,
   "scopes_required": "ads_management,business_management",
   "scopes_requested": "...",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 0,
     "file": "lib/ads/writers/meta.ts",
     "line": 0,
     "snippet": "no /{audienceId}/adaccounts sharing writer"
    }
   ],
   "notes": "NOT IMPLEMENTED."
  },
  {
   "platform": "meta",
   "capability": "pixel create",
   "tier": 3,
   "weight": 1,
   "gate": 5,
   "failing_gate": "G6",
   "vendor_endpoint": "POST https://graph.facebook.com/v21.0/act_{id}/adspixels",
   "api_version": "v21.0",
   "scopes_required": "ads_management",
   "scopes_requested": "...,ads_management,...",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 1,
     "file": "lib/ads/writers/meta.ts",
     "line": 1888,
     "snippet": "POST /adspixels {name}"
    }
   ],
   "notes": "RECONCILED G2->G5."
  },
  {
   "platform": "meta",
   "capability": "CAPI server event send w/ dedup",
   "tier": 3,
   "weight": 1,
   "gate": 5,
   "failing_gate": "G6",
   "vendor_endpoint": "POST https://graph.facebook.com/v21.0/{pixelId}/events",
   "api_version": "v21.0",
   "scopes_required": "pixel/dataset access token (CAPI)",
   "scopes_requested": "...",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 3,
     "file": "lib/capi/send.ts",
     "line": 40,
     "snippet": "requires stored CAPI creds, enforced at send"
    },
    {
     "gate": 5,
     "file": "lib/capi/send.ts",
     "line": 65,
     "snippet": "CapiEventStatus @@unique[brandId,eventId] deterministic dedup"
    }
   ],
   "notes": "STRONGEST-TIER: credential enforced at boundary + dedup + idempotent status table. Only G6 missing."
  },
  {
   "platform": "meta",
   "capability": "dataset / event set config",
   "tier": 3,
   "weight": 1,
   "gate": 5,
   "failing_gate": "G6",
   "vendor_endpoint": "POST https://graph.facebook.com/v21.0/act_{id}/adspixels",
   "api_version": "v21.0",
   "scopes_required": "ads_management,business_management",
   "scopes_requested": "...",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 1,
     "file": "lib/ads/writers/meta.ts",
     "line": 1888,
     "snippet": "createPixel (dataset) is the real write; provisionCapi=GET probe + storeCapiToken (DB-only)"
    }
   ],
   "notes": "DB-ONLY-MASQUERADE flag on provisionCapi config path; real mutation is createPixel. RECONCILED to G5 on createPixel path."
  },
  {
   "platform": "meta",
   "capability": "product catalog create",
   "tier": 3,
   "weight": 1,
   "gate": 5,
   "failing_gate": "G6",
   "vendor_endpoint": "POST https://graph.facebook.com/v21.0/{businessId}/owned_product_catalogs",
   "api_version": "v21.0",
   "scopes_required": "catalog_management",
   "scopes_requested": "...,catalog_management",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 3,
     "file": "lib/ads/writers/meta.ts",
     "line": 1987,
     "snippet": "if(live && !brandHasCatalogScope) refuse — the ONLY Meta write enforcing its scope at the boundary"
    },
    {
     "gate": 5,
     "file": "lib/ads/writers/meta.ts",
     "line": 1994,
     "snippet": "findPriorCreate idempotency + kill-switch"
    }
   ],
   "notes": "STRONGEST-TIER (only boundary-enforced scope). Only G6 missing."
  },
  {
   "platform": "meta",
   "capability": "product set create",
   "tier": 3,
   "weight": 1,
   "gate": 5,
   "failing_gate": "G6",
   "vendor_endpoint": "POST https://graph.facebook.com/v21.0/{catalogId}/product_sets",
   "api_version": "v21.0",
   "scopes_required": "catalog_management",
   "scopes_requested": "...,catalog_management",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 1,
     "file": "lib/ads/writers/meta.ts",
     "line": 2032,
     "snippet": "POST /product_sets {filter}"
    }
   ],
   "notes": "own boundary unguarded but needs a catalog (scope-gated upstream). RECONCILED G2->G5."
  },
  {
   "platform": "meta",
   "capability": "catalog feed schedule",
   "tier": 3,
   "weight": 1,
   "gate": 0,
   "failing_gate": "G1",
   "vendor_endpoint": null,
   "api_version": null,
   "scopes_required": "catalog_management",
   "scopes_requested": "...",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 0,
     "file": "lib/actions/executeVerb.ts",
     "line": 871,
     "snippet": "enable_catalog_sync -> setCatalogSyncEnabled (DB flag). No product_feeds schedule POST"
    }
   ],
   "notes": "DB-ONLY-MASQUERADE."
  },
  {
   "platform": "meta",
   "capability": "DPA campaign wiring",
   "tier": 3,
   "weight": 1,
   "gate": 5,
   "failing_gate": "G6",
   "vendor_endpoint": "POST https://graph.facebook.com/v21.0/act_{id}/adsets",
   "api_version": "v21.0",
   "scopes_required": "ads_management,catalog_management",
   "scopes_requested": "...",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 1,
     "file": "lib/ads/writers/meta.ts",
     "line": 981,
     "snippet": "promoted_object {pixel_id,product_set_id,product_catalog_id,custom_event_type}"
    }
   ],
   "notes": "needs pixel+catalog (honest fail). RECONCILED G2->G5."
  },
  {
   "platform": "meta",
   "capability": "Ad Rules API create",
   "tier": 3,
   "weight": 1,
   "gate": 0,
   "failing_gate": "G1",
   "vendor_endpoint": null,
   "api_version": null,
   "scopes_required": "ads_management",
   "scopes_requested": "...",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 0,
     "file": "lib/ads/writers/meta.ts",
     "line": 0,
     "snippet": "no /adrules_library writer; Cresva 'rules' are app-side detectors"
    }
   ],
   "notes": "NOT IMPLEMENTED."
  },
  {
   "platform": "meta",
   "capability": "naming convention enforce",
   "tier": 3,
   "weight": 1,
   "gate": 0,
   "failing_gate": "G1",
   "vendor_endpoint": null,
   "api_version": null,
   "scopes_required": "n/a",
   "scopes_requested": "...",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 0,
     "file": "lib/tools/registry/actions/post-proposal.ts",
     "line": 0,
     "snippet": "naming applied app-side, not a Meta mutation"
    }
   ],
   "notes": "DB-ONLY (not a platform write)."
  },
  {
   "platform": "meta",
   "capability": "UTM / url tag write",
   "tier": 3,
   "weight": 1,
   "gate": 0,
   "failing_gate": "G1",
   "vendor_endpoint": null,
   "api_version": null,
   "scopes_required": "ads_management",
   "scopes_requested": "...",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 0,
     "file": "lib/ads/writers/meta.ts",
     "line": 1527,
     "snippet": "UTM appended in creative link build; no url_tags mutation verb"
    }
   ],
   "notes": "link-build, not a mutation."
  },
  {
   "platform": "meta",
   "capability": "ad label create",
   "tier": 3,
   "weight": 1,
   "gate": 0,
   "failing_gate": "G1",
   "vendor_endpoint": null,
   "api_version": null,
   "scopes_required": "ads_management",
   "scopes_requested": "...",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 0,
     "file": "lib/ads/writers/meta.ts",
     "line": 0,
     "snippet": "no /adlabels writer"
    }
   ],
   "notes": "NOT IMPLEMENTED."
  },
  {
   "platform": "meta",
   "capability": "comment hide/delete/reply",
   "tier": 3,
   "weight": 1,
   "gate": 0,
   "failing_gate": "G1",
   "vendor_endpoint": null,
   "api_version": null,
   "scopes_required": "pages_manage_engagement",
   "scopes_requested": "NOT requested",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 0,
     "file": "lib/ads/writers/meta.ts",
     "line": 0,
     "snippet": "no /comments writer; page scope not requested"
    }
   ],
   "notes": "NOT IMPLEMENTED."
  },
  {
   "platform": "meta",
   "capability": "page post boost",
   "tier": 3,
   "weight": 1,
   "gate": 0,
   "failing_gate": "G1",
   "vendor_endpoint": null,
   "api_version": null,
   "scopes_required": "ads_management,pages_manage_ads",
   "scopes_requested": "pages scope NOT requested",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 0,
     "file": "lib/ads/writers/meta.ts",
     "line": 0,
     "snippet": "no /promotions boost writer"
    }
   ],
   "notes": "NOT IMPLEMENTED."
  },
  {
   "platform": "meta",
   "capability": "business asset assignment",
   "tier": 3,
   "weight": 1,
   "gate": 0,
   "failing_gate": "G1",
   "vendor_endpoint": null,
   "api_version": null,
   "scopes_required": "business_management",
   "scopes_requested": "business_management (requested)",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 0,
     "file": "lib/ads/writers/meta.ts",
     "line": 0,
     "snippet": "no assigned_users/business-asset writer"
    }
   ],
   "notes": "NOT IMPLEMENTED."
  },
  {
   "platform": "google",
   "capability": "campaign budget mutate",
   "tier": 1,
   "weight": 3,
   "gate": 5,
   "failing_gate": "G6",
   "vendor_endpoint": "google-ads-api SDK CampaignBudgetService.Mutate @ googleads.googleapis.com/v21",
   "api_version": "v21",
   "scopes_required": "auth/adwords",
   "scopes_requested": "auth/adwords,auth/content",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 1,
     "file": "lib/ads/writers/google.ts",
     "line": 447,
     "snippet": "customer.campaignBudgets.update([{amount_micros}])"
    },
    {
     "gate": 4,
     "file": "lib/actions/modifiers/index.ts",
     "line": 192,
     "snippet": "Math.round(x*1_000_000) micros correct"
    }
   ],
   "notes": "shared-budget refusal + day-cap. G6=0."
  },
  {
   "platform": "google",
   "capability": "campaign status mutate",
   "tier": 1,
   "weight": 3,
   "gate": 5,
   "failing_gate": "G6",
   "vendor_endpoint": "google-ads-api SDK CampaignService.Mutate @ v21",
   "api_version": "v21",
   "scopes_required": "auth/adwords",
   "scopes_requested": "auth/adwords,auth/content",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 1,
     "file": "lib/ads/writers/google.ts",
     "line": 193,
     "snippet": "campaigns.update status=PAUSED"
    }
   ],
   "notes": "REMOVED guard + idempotent-noop + GoogleAdsFailure mapping."
  },
  {
   "platform": "google",
   "capability": "ad group status mutate",
   "tier": 1,
   "weight": 3,
   "gate": 5,
   "failing_gate": "G6",
   "vendor_endpoint": "google-ads-api SDK AdGroupService.Mutate @ v21",
   "api_version": "v21",
   "scopes_required": "auth/adwords",
   "scopes_requested": "auth/adwords,auth/content",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 1,
     "file": "lib/ads/writers/google.ts",
     "line": 606,
     "snippet": "adGroups.update status=PAUSED"
    }
   ],
   "notes": "G6=0."
  },
  {
   "platform": "google",
   "capability": "bidding strategy change (tCPA/tROAS/maximize)",
   "tier": 1,
   "weight": 3,
   "gate": 5,
   "failing_gate": "G6",
   "vendor_endpoint": "google-ads-api SDK CampaignService.Mutate @ v21",
   "api_version": "v21",
   "scopes_required": "auth/adwords",
   "scopes_requested": "auth/adwords,auth/content",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 4,
     "file": "lib/ads/writers/google.ts",
     "line": 534,
     "snippet": "enum-correct oneof; tCPA needs micros, tROAS needs ratio; reads prev"
    }
   ],
   "notes": "Google validates eligibility -> honest FAILED."
  },
  {
   "platform": "google",
   "capability": "target value set",
   "tier": 1,
   "weight": 3,
   "gate": 5,
   "failing_gate": "G6",
   "vendor_endpoint": "google-ads-api SDK CampaignService.Mutate @ v21",
   "api_version": "v21",
   "scopes_required": "auth/adwords",
   "scopes_requested": "auth/adwords,auth/content",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 1,
     "file": "lib/ads/writers/google.ts",
     "line": 536,
     "snippet": "target_cpa_micros / target_roas"
    }
   ],
   "notes": "micros correct."
  },
  {
   "platform": "google",
   "capability": "ad status mutate",
   "tier": 1,
   "weight": 3,
   "gate": 1,
   "failing_gate": "G2",
   "vendor_endpoint": "google-ads-api SDK AdGroupAdService.Mutate (only via editRsa)",
   "api_version": "v21",
   "scopes_required": "auth/adwords",
   "scopes_requested": "auth/adwords,auth/content",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 1,
     "file": "lib/ads/writers/google.ts",
     "line": 1170,
     "snippet": "ad_group_ad status flip ONLY inside editResponsiveSearchAd"
    },
    {
     "gate": 2,
     "file": "lib/actions/executeVerb.ts",
     "line": 524,
     "snippet": "pause_ad register is Meta; no standalone Google ad-status verb"
    }
   ],
   "notes": "exists in code but not independently reachable => fails G2. TIER-1 GAP."
  },
  {
   "platform": "google",
   "capability": "keyword status/bid mutate",
   "tier": 1,
   "weight": 3,
   "gate": 5,
   "failing_gate": "G6",
   "vendor_endpoint": "google-ads-api SDK AdGroupCriterionService.Mutate @ v21",
   "api_version": "v21",
   "scopes_required": "auth/adwords",
   "scopes_requested": "auth/adwords,auth/content",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 1,
     "file": "lib/ads/writers/google.ts",
     "line": 1096,
     "snippet": "mutateKeywordStatus update_mask status ONLY"
    }
   ],
   "notes": "STATUS mutate G5; keyword BID mutate NOT implemented (cpc only at add time)."
  },
  {
   "platform": "google",
   "capability": "campaign end date/schedule mutate",
   "tier": 1,
   "weight": 3,
   "gate": 0,
   "failing_gate": "G1",
   "vendor_endpoint": null,
   "api_version": null,
   "scopes_required": "auth/adwords",
   "scopes_requested": "auth/adwords,auth/content",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 0,
     "file": "lib/ads/writers/google.ts",
     "line": 879,
     "snippet": "start_date only at create; no end_date/ad_schedule UPDATE writer"
    }
   ],
   "notes": "NOT IMPLEMENTED. TIER-1 GAP."
  },
  {
   "platform": "google",
   "capability": "campaign create",
   "tier": 2,
   "weight": 2,
   "gate": 5,
   "failing_gate": "G6",
   "vendor_endpoint": "google-ads-api SDK GoogleAdsService.Mutate (budget+campaign) @ v21",
   "api_version": "v21",
   "scopes_required": "auth/adwords",
   "scopes_requested": "auth/adwords,auth/content",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 1,
     "file": "lib/ads/writers/google.ts",
     "line": 919,
     "snippet": "mutateResources atomic budget+campaign"
    }
   ],
   "notes": "merchant-feed preflight; PAUSED; rollback=google_remove_campaign."
  },
  {
   "platform": "google",
   "capability": "ad group create",
   "tier": 2,
   "weight": 2,
   "gate": 5,
   "failing_gate": "G6",
   "vendor_endpoint": "google-ads-api SDK AdGroupService.Mutate @ v21",
   "api_version": "v21",
   "scopes_required": "auth/adwords",
   "scopes_requested": "auth/adwords,auth/content",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 1,
     "file": "lib/ads/writers/google.ts",
     "line": 1010,
     "snippet": "mutateResources ad_group create PAUSED"
    }
   ],
   "notes": "rollback google_remove_adgroup."
  },
  {
   "platform": "google",
   "capability": "RSA create w/ assets and pinning",
   "tier": 2,
   "weight": 2,
   "gate": 5,
   "failing_gate": "G6",
   "vendor_endpoint": "google-ads-api SDK AdGroupAdService.Mutate @ v21",
   "api_version": "v21",
   "scopes_required": "auth/adwords",
   "scopes_requested": "auth/adwords,auth/content",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 4,
     "file": "lib/ads/writers/google.ts",
     "line": 1120,
     "snippet": "headlines pinned_field via ServedAssetFieldType; final_urls; PAUSED"
    }
   ],
   "notes": "pinning implemented."
  },
  {
   "platform": "google",
   "capability": "keyword add",
   "tier": 2,
   "weight": 2,
   "gate": 5,
   "failing_gate": "G6",
   "vendor_endpoint": "google-ads-api SDK AdGroupCriterionService.Mutate @ v21",
   "api_version": "v21",
   "scopes_required": "auth/adwords",
   "scopes_requested": "auth/adwords,auth/content",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 1,
     "file": "lib/ads/writers/google.ts",
     "line": 1054,
     "snippet": "mutateResources N ad_group_criterion create"
    }
   ],
   "notes": "batch = one call."
  },
  {
   "platform": "google",
   "capability": "negative keyword add",
   "tier": 2,
   "weight": 2,
   "gate": 5,
   "failing_gate": "G6",
   "vendor_endpoint": "google-ads-api SDK Campaign/AdGroupCriterionService.Mutate @ v21",
   "api_version": "v21",
   "scopes_required": "auth/adwords",
   "scopes_requested": "auth/adwords,auth/content",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 1,
     "file": "lib/ads/writers/google.ts",
     "line": 1081,
     "snippet": "campaign_criterion|ad_group_criterion negative:true"
    }
   ],
   "notes": "campaign+adgroup only; SHARED-LIST level absent."
  },
  {
   "platform": "google",
   "capability": "shared negative list create+attach",
   "tier": 2,
   "weight": 2,
   "gate": 0,
   "failing_gate": "G1",
   "vendor_endpoint": null,
   "api_version": null,
   "scopes_required": "auth/adwords",
   "scopes_requested": "auth/adwords,auth/content",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 0,
     "file": "lib/ads/writers/google.ts",
     "line": 1072,
     "snippet": "no SharedSet/SharedCriterion/CampaignSharedSet writer"
    }
   ],
   "notes": "NOT IMPLEMENTED."
  },
  {
   "platform": "google",
   "capability": "audience signal attach",
   "tier": 2,
   "weight": 2,
   "gate": 5,
   "failing_gate": "G6",
   "vendor_endpoint": "google-ads-api SDK AssetGroupSignalService.Mutate @ v21",
   "api_version": "v21",
   "scopes_required": "auth/adwords",
   "scopes_requested": "auth/adwords,auth/content",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 1,
     "file": "lib/ads/writers/google.ts",
     "line": 1273,
     "snippet": "asset_group_signal create audience(userList)+search_theme"
    }
   ],
   "notes": "G6=0."
  },
  {
   "platform": "google",
   "capability": "PMax asset group create/update",
   "tier": 2,
   "weight": 2,
   "gate": 5,
   "failing_gate": "G6",
   "vendor_endpoint": "google-ads-api SDK GoogleAdsService.Mutate @ v21",
   "api_version": "v21",
   "scopes_required": "auth/adwords",
   "scopes_requested": "auth/adwords,auth/content",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 1,
     "file": "lib/ads/writers/google.ts",
     "line": 1238,
     "snippet": "atomic assets(temp ids)->asset_group->asset_group_asset PAUSED"
    }
   ],
   "notes": "CREATE only; no UPDATE. base64 image upload unverified live."
  },
  {
   "platform": "google",
   "capability": "listing group/product partition tree edit",
   "tier": 2,
   "weight": 2,
   "gate": 0,
   "failing_gate": "G1",
   "vendor_endpoint": null,
   "api_version": null,
   "scopes_required": "auth/adwords",
   "scopes_requested": "auth/adwords,auth/content",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 0,
     "file": "lib/ads/writers/google-pmax-schemas.ts",
     "line": 39,
     "snippet": "listingGroupFilter is a dead schema field; no mutate op"
    }
   ],
   "notes": "NOT IMPLEMENTED (dead schema)."
  },
  {
   "platform": "google",
   "capability": "ad extension (asset) create+link",
   "tier": 2,
   "weight": 2,
   "gate": 0,
   "failing_gate": "G1",
   "vendor_endpoint": null,
   "api_version": null,
   "scopes_required": "auth/adwords",
   "scopes_requested": "auth/adwords,auth/content",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 0,
     "file": "lib/ads/writers/google.ts",
     "line": 0,
     "snippet": "no sitelink/callout/campaign_asset writer"
    }
   ],
   "notes": "NOT IMPLEMENTED."
  },
  {
   "platform": "google",
   "capability": "geo & language targeting mutate",
   "tier": 2,
   "weight": 2,
   "gate": 0,
   "failing_gate": "G1",
   "vendor_endpoint": null,
   "api_version": null,
   "scopes_required": "auth/adwords",
   "scopes_requested": "auth/adwords,auth/content",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 0,
     "file": "lib/ads/writers/google.ts",
     "line": 0,
     "snippet": "no location_criterion/language_constant writer"
    }
   ],
   "notes": "NOT IMPLEMENTED."
  },
  {
   "platform": "google",
   "capability": "device bid modifier",
   "tier": 2,
   "weight": 2,
   "gate": 0,
   "failing_gate": "G1",
   "vendor_endpoint": null,
   "api_version": null,
   "scopes_required": "auth/adwords",
   "scopes_requested": "auth/adwords,auth/content",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 0,
     "file": "lib/ads/writers/google.ts",
     "line": 0,
     "snippet": "no campaign_bid_modifier writer"
    }
   ],
   "notes": "NOT IMPLEMENTED."
  },
  {
   "platform": "google",
   "capability": "drafts & experiments create",
   "tier": 2,
   "weight": 2,
   "gate": 4,
   "failing_gate": "G5",
   "vendor_endpoint": "google-ads-api SDK ExperimentService.Mutate @ v21",
   "api_version": "v21",
   "scopes_required": "auth/adwords",
   "scopes_requested": "auth/adwords,auth/content",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 4,
     "file": "lib/experiments/google.ts",
     "line": 8,
     "snippet": "SELF-FLAGGED wire needs one live run; type SEARCH_CUSTOM; no rollback verb"
    }
   ],
   "notes": "DRAFTS absent; experiments self-admitted unverified => G4."
  },
  {
   "platform": "google",
   "capability": "conversion action create",
   "tier": 3,
   "weight": 1,
   "gate": 5,
   "failing_gate": "G6",
   "vendor_endpoint": "google-ads-api SDK ConversionActionService.Mutate @ v21",
   "api_version": "v21",
   "scopes_required": "auth/adwords",
   "scopes_requested": "auth/adwords,auth/content",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 4,
     "file": "lib/ads/writers/google.ts",
     "line": 1291,
     "snippet": "default_value is a double (correct, not micros)"
    }
   ],
   "notes": "G6=0."
  },
  {
   "platform": "google",
   "capability": "conversion action update",
   "tier": 3,
   "weight": 1,
   "gate": 5,
   "failing_gate": "G6",
   "vendor_endpoint": "google-ads-api SDK ConversionActionService.Mutate @ v21",
   "api_version": "v21",
   "scopes_required": "auth/adwords",
   "scopes_requested": "auth/adwords,auth/content",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 1,
     "file": "lib/ads/writers/google.ts",
     "line": 1338,
     "snippet": "update with update_mask paths"
    }
   ],
   "notes": "added capability (not in canonical list)."
  },
  {
   "platform": "google",
   "capability": "offline conversion upload / enhanced conversions",
   "tier": 3,
   "weight": 1,
   "gate": 0,
   "failing_gate": "G1",
   "vendor_endpoint": null,
   "api_version": null,
   "scopes_required": "auth/adwords",
   "scopes_requested": "auth/adwords,auth/content",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 0,
     "file": "lib/ads/writers/google-customer-match.ts",
     "line": 98,
     "snippet": "OfflineUserDataJob is CUSTOMER_MATCH not click-conversion upload; no uploadClickConversions"
    }
   ],
   "notes": "NOT IMPLEMENTED."
  },
  {
   "platform": "google",
   "capability": "customer match list create+upload",
   "tier": 3,
   "weight": 1,
   "gate": 4,
   "failing_gate": "G5",
   "vendor_endpoint": "google-ads-api SDK UserListService + OfflineUserDataJobService @ v21",
   "api_version": "v21",
   "scopes_required": "auth/adwords",
   "scopes_requested": "auth/adwords,auth/content",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 4,
     "file": "lib/ads/writers/google-customer-match.ts",
     "line": 99,
     "snippet": "(customer as unknown).offlineUserDataJobs CAST; self-flagged 'needs live confirm'"
    }
   ],
   "notes": "list-create solid; upload state-machine untyped+unverified => G4. Zero-PII."
  },
  {
   "platform": "google",
   "capability": "conversion value rules",
   "tier": 3,
   "weight": 1,
   "gate": 0,
   "failing_gate": "G1",
   "vendor_endpoint": null,
   "api_version": null,
   "scopes_required": "auth/adwords",
   "scopes_requested": "auth/adwords,auth/content",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 0,
     "file": "lib/ads/writers/google.ts",
     "line": 0,
     "snippet": "no conversion_value_rule writer"
    }
   ],
   "notes": "NOT IMPLEMENTED."
  },
  {
   "platform": "google",
   "capability": "recommendations apply/dismiss",
   "tier": 3,
   "weight": 1,
   "gate": 0,
   "failing_gate": "G1",
   "vendor_endpoint": null,
   "api_version": null,
   "scopes_required": "auth/adwords",
   "scopes_requested": "auth/adwords,auth/content",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 0,
     "file": "lib/ads/writers/google.ts",
     "line": 0,
     "snippet": "no RecommendationService apply/dismiss"
    }
   ],
   "notes": "NOT IMPLEMENTED."
  },
  {
   "platform": "google",
   "capability": "label create+apply",
   "tier": 3,
   "weight": 1,
   "gate": 0,
   "failing_gate": "G1",
   "vendor_endpoint": null,
   "api_version": null,
   "scopes_required": "auth/adwords",
   "scopes_requested": "auth/adwords,auth/content",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 0,
     "file": "lib/ads/writers/google.ts",
     "line": 0,
     "snippet": "no LabelService writer"
    }
   ],
   "notes": "NOT IMPLEMENTED."
  },
  {
   "platform": "google",
   "capability": "portfolio bid strategy create",
   "tier": 3,
   "weight": 1,
   "gate": 0,
   "failing_gate": "G1",
   "vendor_endpoint": null,
   "api_version": null,
   "scopes_required": "auth/adwords",
   "scopes_requested": "auth/adwords,auth/content",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 0,
     "file": "lib/ads/writers/google.ts",
     "line": 0,
     "snippet": "no shared bidding_strategy writer; campaign-level only"
    }
   ],
   "notes": "NOT IMPLEMENTED."
  },
  {
   "platform": "google",
   "capability": "campaign-level exclusions",
   "tier": 3,
   "weight": 1,
   "gate": 1,
   "failing_gate": "G2",
   "vendor_endpoint": "google-ads-api SDK CampaignCriterionService.Mutate (neg-kw only)",
   "api_version": "v21",
   "scopes_required": "auth/adwords",
   "scopes_requested": "auth/adwords,auth/content",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 1,
     "file": "lib/ads/writers/google.ts",
     "line": 1074,
     "snippet": "campaign negative keyword only; no placement/content/IP/topic exclusion"
    }
   ],
   "notes": "only neg-kw exclusions."
  },
  {
   "platform": "google",
   "capability": "budget order / account-level edits",
   "tier": 3,
   "weight": 1,
   "gate": 0,
   "failing_gate": "G1",
   "vendor_endpoint": null,
   "api_version": null,
   "scopes_required": "auth/adwords",
   "scopes_requested": "auth/adwords,auth/content",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 0,
     "file": "lib/ads/writers/google.ts",
     "line": 0,
     "snippet": "no BudgetOrder/AccountBudget/CustomerService writer"
    }
   ],
   "notes": "NOT IMPLEMENTED."
  },
  {
   "platform": "shopify",
   "capability": "product price/variant update",
   "tier": 1,
   "weight": 3,
   "gate": 4,
   "failing_gate": "G5",
   "vendor_endpoint": "PUT https://{shop}/admin/api/2024-01/variants/{id}.json",
   "api_version": "2026-07 (STALE)",
   "scopes_required": "write_products",
   "scopes_requested": "write_products",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 1,
     "file": "lib/ads/writers/shopify.ts",
     "line": 817,
     "snippet": "PUT variants/{id}.json {price}"
    },
    {
     "gate": 4,
     "file": "lib/ads/writers/shopify.ts",
     "line": 777,
     "snippet": "assertPriceBounds; money decimal string"
    }
   ],
   "notes": "[Prompt 2] SHOPIFY_ADMIN_API_VERSION default bumped 2024-01 -> 2026-07 (supported). [ADDENDUM correction (a): staleness cap G5->G4 — 2024-01 (STALE)] STALENESS: REST product-write on Shopify hard-deprecation track. No pre-flight scope gate (vendor 403 only).",
   "audit_gate": 5,
   "revised": {
    "sprint": "Prompt 2 contract fix",
    "from": 5,
    "to": 4,
    "status": "stands",
    "why": "demoted G5 to G4 by the contract review."
   }
  },
  {
   "platform": "shopify",
   "capability": "inventory level set",
   "tier": 1,
   "weight": 3,
   "gate": 4,
   "failing_gate": "G5",
   "vendor_endpoint": "POST https://{shop}/admin/api/2024-01/inventory_levels/set.json",
   "api_version": "2026-07",
   "scopes_required": "write_inventory",
   "scopes_requested": "write_inventory",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 1,
     "file": "lib/ads/writers/shopify.ts",
     "line": 1045,
     "snippet": "POST inventory_levels/set.json"
    }
   ],
   "notes": "[Prompt 2] SHOPIFY_ADMIN_API_VERSION default bumped 2024-01 -> 2026-07 (supported). [ADDENDUM correction (a): staleness cap G5->G4 — 2024-01] write_inventory OMITTED from REQUIRED_SHOPIFY_WRITE_SCOPES readback (check-write-scopes.ts:32) => false-green banner.",
   "audit_gate": 5,
   "revised": {
    "sprint": "Prompt 2 contract fix",
    "from": 5,
    "to": 4,
    "status": "stands",
    "why": "demoted G5 to G4 by the contract review."
   }
  },
  {
   "platform": "shopify",
   "capability": "product publish/unpublish",
   "tier": 1,
   "weight": 3,
   "gate": 4,
   "failing_gate": "G5",
   "vendor_endpoint": "PUT https://{shop}/admin/api/2024-01/products/{id}.json",
   "api_version": "2026-07 (STALE)",
   "scopes_required": "write_products",
   "scopes_requested": "write_products",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 1,
     "file": "lib/ads/writers/shopify.ts",
     "line": 437,
     "snippet": "PUT products/{id}.json {status}"
    }
   ],
   "notes": "[Prompt 2] SHOPIFY_ADMIN_API_VERSION default bumped 2024-01 -> 2026-07 (supported). [ADDENDUM correction (a): staleness cap G5->G4 — 2024-01 (STALE)] REST product write deprecated vs GraphQL.",
   "audit_gate": 5,
   "revised": {
    "sprint": "Prompt 2 contract fix",
    "from": 5,
    "to": 4,
    "status": "stands",
    "why": "demoted G5 to G4 by the contract review."
   }
  },
  {
   "platform": "shopify",
   "capability": "discount code create/deactivate",
   "tier": 1,
   "weight": 3,
   "gate": 4,
   "failing_gate": "G5",
   "vendor_endpoint": "POST https://{shop}/admin/api/2024-01/price_rules.json (+discount_codes.json)",
   "api_version": "2026-07",
   "scopes_required": "write_discounts",
   "scopes_requested": "write_discounts",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 5,
     "file": "lib/ads/writers/shopify.ts",
     "line": 371,
     "snippet": "orphan PriceRule cleanup DELETE + cleanup_partial"
    }
   ],
   "notes": "[Prompt 2] SHOPIFY_ADMIN_API_VERSION default bumped 2024-01 -> 2026-07 (supported). [ADDENDUM correction (a): staleness cap G5->G4 — 2024-01] default full=AUTO (autonomous-eligible). deleteDiscount 'reversal' re-creates new id (not true undo).",
   "audit_gate": 5,
   "revised": {
    "sprint": "Prompt 2 contract fix",
    "from": 5,
    "to": 4,
    "status": "stands",
    "why": "demoted G5 to G4 by the contract review."
   }
  },
  {
   "platform": "shopify",
   "capability": "automatic discount create",
   "tier": 1,
   "weight": 3,
   "gate": 0,
   "failing_gate": "G1",
   "vendor_endpoint": null,
   "api_version": null,
   "scopes_required": "write_discounts",
   "scopes_requested": "write_discounts",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 0,
     "file": "lib/ads/writers/shopify.ts",
     "line": 160,
     "snippet": "only CODE discount; no discountAutomaticBasicCreate (needs GraphQL; zero GraphQL writers)"
    }
   ],
   "notes": "NOT IMPLEMENTED."
  },
  {
   "platform": "shopify",
   "capability": "product create",
   "tier": 2,
   "weight": 2,
   "gate": 0,
   "failing_gate": "G1",
   "vendor_endpoint": null,
   "api_version": null,
   "scopes_required": "write_products",
   "scopes_requested": "write_products",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 0,
     "file": "lib/actions/reversibility.ts",
     "line": 749,
     "snippet": "comment: removed unwired phantoms (shopify_product_create...)"
    }
   ],
   "notes": "NOT IMPLEMENTED (only status-flip).",
   "merged_in_a_later_edit": true,
   "merge_note": "The audit scored product create and variant create as two capabilities. A later edit merged them into one row, which is why the file held 129 rows while _meta and compute.mjs describe 130. Split back 2026-09-05; both were gate 0 in the audit and remain so."
  },
  {
   "platform": "shopify",
   "capability": "variant create",
   "tier": 2,
   "weight": 2,
   "gate": 0,
   "failing_gate": "G1",
   "vendor_endpoint": null,
   "api_version": null,
   "scopes_required": "write_products",
   "scopes_requested": "write_products",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 0,
     "file": "lib/actions/reversibility.ts",
     "line": 749,
     "snippet": "comment: removed unwired phantoms (shopify_product_create...)"
    }
   ],
   "notes": "NOT IMPLEMENTED (only status-flip).",
   "merged_in_a_later_edit": true,
   "merge_note": "The audit scored product create and variant create as two capabilities. A later edit merged them into one row, which is why the file held 129 rows while _meta and compute.mjs describe 130. Split back 2026-09-05; both were gate 0 in the audit and remain so."
  },
  {
   "platform": "shopify",
   "capability": "collection create + product assignment",
   "tier": 2,
   "weight": 2,
   "gate": 4,
   "failing_gate": "G5",
   "vendor_endpoint": "POST/DELETE https://{shop}/admin/api/2024-01/custom_collections.json + collects.json",
   "api_version": "2026-07",
   "scopes_required": "write_products",
   "scopes_requested": "write_products",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 1,
     "file": "lib/ads/writers/shopify.ts",
     "line": 1077,
     "snippet": "POST custom_collections.json; collects.json:888"
    }
   ],
   "notes": "[Prompt 2] SHOPIFY_ADMIN_API_VERSION default bumped 2024-01 -> 2026-07 (supported). [ADDENDUM correction (a): staleness cap G5->G4 — 2024-01] CUSTOM collections only; symmetric add/remove idempotent.",
   "audit_gate": 5,
   "revised": {
    "sprint": "Prompt 2 contract fix",
    "from": 5,
    "to": 4,
    "status": "stands",
    "why": "demoted G5 to G4 by the contract review."
   }
  },
  {
   "platform": "shopify",
   "capability": "metafield write (product/variant/shop)",
   "tier": 2,
   "weight": 2,
   "gate": 0,
   "failing_gate": "G1",
   "vendor_endpoint": null,
   "api_version": null,
   "scopes_required": "write_products",
   "scopes_requested": "NOT requested",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 0,
     "file": "lib/ads/writers/shopify.ts",
     "line": 1,
     "snippet": "no metafields.json writer"
    }
   ],
   "notes": "NOT IMPLEMENTED."
  },
  {
   "platform": "shopify",
   "capability": "draft order create",
   "tier": 2,
   "weight": 2,
   "gate": 0,
   "failing_gate": "G1",
   "vendor_endpoint": null,
   "api_version": null,
   "scopes_required": "write_draft_orders",
   "scopes_requested": "NOT requested",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 0,
     "file": "lib/ads/writers/shopify.ts",
     "line": 1,
     "snippet": "no draft_orders.json writer"
    }
   ],
   "notes": "NOT IMPLEMENTED."
  },
  {
   "platform": "shopify",
   "capability": "customer tag write",
   "tier": 2,
   "weight": 2,
   "gate": 0,
   "failing_gate": "G1",
   "vendor_endpoint": null,
   "api_version": null,
   "scopes_required": "write_customers",
   "scopes_requested": "NOT requested",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 0,
     "file": "lib/ads/writers/shopify.ts",
     "line": 1,
     "snippet": "no customers PUT writer"
    }
   ],
   "notes": "NOT IMPLEMENTED."
  },
  {
   "platform": "shopify",
   "capability": "marketing activity create",
   "tier": 2,
   "weight": 2,
   "gate": 4,
   "failing_gate": "G5",
   "vendor_endpoint": "POST https://{shop}/admin/api/2024-01/marketing_events.json",
   "api_version": "2026-07",
   "scopes_required": "write_marketing_events",
   "scopes_requested": "write_marketing_events",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 1,
     "file": "lib/ads/writers/shopify.ts",
     "line": 1104,
     "snippet": "POST marketing_events.json {utm_campaign,...}"
    }
   ],
   "notes": "[Prompt 2] SHOPIFY_ADMIN_API_VERSION default bumped 2024-01 -> 2026-07 (supported). [ADDENDUM correction (a): staleness cap G5->G4 — 2024-01] default full=AUTO. write_marketing_events NOT in readback => false-green banner.",
   "audit_gate": 5,
   "revised": {
    "sprint": "Prompt 2 contract fix",
    "from": 5,
    "to": 4,
    "status": "stands",
    "why": "demoted G5 to G4 by the contract review."
   }
  },
  {
   "platform": "shopify",
   "capability": "webhook subscribe/unsubscribe",
   "tier": 3,
   "weight": 1,
   "gate": 0,
   "failing_gate": "G1",
   "vendor_endpoint": null,
   "api_version": null,
   "scopes_required": "n/a",
   "scopes_requested": "none",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 0,
     "file": "lib/ads/writers/shopify.ts",
     "line": 1,
     "snippet": "no webhooks.json writer"
    }
   ],
   "notes": "NOT IMPLEMENTED."
  },
  {
   "platform": "shopify",
   "capability": "script tag / app embed write",
   "tier": 3,
   "weight": 1,
   "gate": 0,
   "failing_gate": "G1",
   "vendor_endpoint": null,
   "api_version": null,
   "scopes_required": "write_script_tags",
   "scopes_requested": "none",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 0,
     "file": "lib/ads/writers/shopify.ts",
     "line": 1,
     "snippet": "no script_tags.json writer"
    }
   ],
   "notes": "NOT IMPLEMENTED."
  },
  {
   "platform": "shopify",
   "capability": "price rule update",
   "tier": 3,
   "weight": 1,
   "gate": 0,
   "failing_gate": "G1",
   "vendor_endpoint": null,
   "api_version": null,
   "scopes_required": "write_price_rules",
   "scopes_requested": "write_discounts (create only)",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 0,
     "file": "lib/ads/writers/shopify.ts",
     "line": 1,
     "snippet": "no PUT price_rules/{id} update writer"
    }
   ],
   "notes": "NOT IMPLEMENTED (create only)."
  },
  {
   "platform": "shopify",
   "capability": "catalog publication write",
   "tier": 3,
   "weight": 1,
   "gate": 0,
   "failing_gate": "G1",
   "vendor_endpoint": null,
   "api_version": null,
   "scopes_required": "write_publications",
   "scopes_requested": "none",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 0,
     "file": "lib/ads/writers/shopify.ts",
     "line": 1,
     "snippet": "no publications writer"
    }
   ],
   "notes": "NOT IMPLEMENTED."
  },
  {
   "platform": "shopify",
   "capability": "translation / SEO field write",
   "tier": 3,
   "weight": 1,
   "gate": 0,
   "failing_gate": "G1",
   "vendor_endpoint": null,
   "api_version": null,
   "scopes_required": "write_translations",
   "scopes_requested": "none",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 0,
     "file": "lib/ads/writers/shopify.ts",
     "line": 1,
     "snippet": "no translations writer"
    }
   ],
   "notes": "NOT IMPLEMENTED."
  },
  {
   "platform": "shopify",
   "capability": "ACP / agentic-commerce feed writes",
   "tier": 3,
   "weight": 1,
   "gate": 0,
   "failing_gate": "G1",
   "vendor_endpoint": null,
   "api_version": null,
   "scopes_required": "varies",
   "scopes_requested": "none",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 0,
     "file": "lib/ads/writers/shopify.ts",
     "line": 1,
     "snippet": "no ACP feed write endpoints in writer module"
    }
   ],
   "notes": "NOT IMPLEMENTED."
  },
  {
   "platform": "klaviyo",
   "capability": "profile create/update",
   "tier": 1,
   "weight": 3,
   "gate": 0,
   "failing_gate": "G1",
   "vendor_endpoint": null,
   "api_version": "2024-10-15",
   "scopes_required": "profiles:write",
   "scopes_requested": "none (API-key implicit)",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 0,
     "file": "lib/ads/writers/klaviyo.ts",
     "line": 0,
     "snippet": "no createProfile/updateProfile writer"
    }
   ],
   "notes": "UNIMPLEMENTED. TIER-1 GAP."
  },
  {
   "platform": "klaviyo",
   "capability": "list subscribe/unsubscribe (consent)",
   "tier": 1,
   "weight": 3,
   "gate": 0,
   "failing_gate": "G1",
   "vendor_endpoint": null,
   "api_version": "2024-10-15",
   "scopes_required": "lists:write,profiles:write",
   "scopes_requested": "none",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 0,
     "file": "lib/ads/writers/klaviyo.ts",
     "line": 0,
     "snippet": "no subscription-bulk-create-jobs writer"
    }
   ],
   "notes": "UNIMPLEMENTED. TIER-1 GAP."
  },
  {
   "platform": "klaviyo",
   "capability": "suppression add/remove",
   "tier": 1,
   "weight": 3,
   "gate": 0,
   "failing_gate": "G1",
   "vendor_endpoint": null,
   "api_version": "2024-10-15",
   "scopes_required": "profiles:write",
   "scopes_requested": "none",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 0,
     "file": "lib/ads/writers/klaviyo.ts",
     "line": 0,
     "snippet": "no suppression-bulk writer"
    }
   ],
   "notes": "UNIMPLEMENTED. TIER-1 GAP."
  },
  {
   "platform": "klaviyo",
   "capability": "segment create/update",
   "tier": 2,
   "weight": 2,
   "gate": 4,
   "failing_gate": "G5",
   "vendor_endpoint": "POST/PATCH https://a.klaviyo.com/api/segments",
   "api_version": "2024-10-15 (STALE)",
   "scopes_required": "n/a (API key)",
   "scopes_requested": "none",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 1,
     "file": "lib/ads/writers/klaviyo.ts",
     "line": 1002,
     "snippet": "POST segments {data:{type:segment}}"
    },
    {
     "gate": 4,
     "file": "lib/ads/writers/klaviyo-internal.ts",
     "line": 236,
     "snippet": "mapKlaviyoErrorToWriterError full JSON:API taxonomy"
    }
   ],
   "notes": "[ADDENDUM correction (a): staleness cap G5->G4 — 2024-10-15 (STALE)] correct JSON:API. revision stale.",
   "audit_gate": 5,
   "revised": {
    "sprint": "unrecorded",
    "from": 5,
    "to": 4,
    "status": "stands",
    "why": "Demoted G5 to G4 with no annotation. No sprint, no date and no reason was recorded at the time; this stamp records only that the change happened and that its justification is unknown."
   }
  },
  {
   "platform": "klaviyo",
   "capability": "campaign create",
   "tier": 2,
   "weight": 2,
   "gate": 0,
   "failing_gate": "G1",
   "vendor_endpoint": null,
   "api_version": "2024-10-15",
   "scopes_required": "campaigns:write",
   "scopes_requested": "none",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 0,
     "file": "lib/ads/writers/klaviyo.ts",
     "line": 0,
     "snippet": "only schedule/send/cancel of EXISTING draft; no POST /campaigns create"
    }
   ],
   "notes": "UNIMPLEMENTED."
  },
  {
   "platform": "klaviyo",
   "capability": "campaign send/schedule",
   "tier": 2,
   "weight": 2,
   "gate": 3,
   "failing_gate": "G5",
   "vendor_endpoint": "POST https://a.klaviyo.com/api/campaigns/{id}/jobs/send (LIKELY WRONG)",
   "api_version": "2024-10-15",
   "scopes_required": "n/a (API key)",
   "scopes_requested": "none",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 4,
     "file": "lib/ads/writers/klaviyo.ts",
     "line": 538,
     "snippet": "code concedes endpoint is a 'convention'; real Klaviyo = POST /api/campaign-send-jobs, no /jobs/send sub-resource"
    }
   ],
   "notes": "[Prompt 2 CONTRACT FIX] endpoint corrected to the doc-verified POST /api/campaign-send-jobs + PATCH /api/campaigns/{id} send_strategy + PATCH cancel action; was G3 (invented jobs/send). Now contract-correct (G4), still shadow/unproven. G4 FAIL: invented endpoint likely 404s; also breaks schedule's own cancel-rollback (same wrong path). No Idempotency-Key => double-send risk. IRREVERSIBLE send.",
   "audit_gate": 3,
   "revised": {
    "sprint": "Prompt 2 contract fix",
    "from": 3,
    "to": null,
    "status": "withdrawn 2026-09-05",
    "why": "PROMOTION WITHDRAWN 2026-09-05. The sprint recorded G3 to G4 as contract-correct, in the same notes field that reads 'G4 FAIL: invented endpoint likely 404s', while vendor_endpoint still carries (LIKELY WRONG) and the gate-4 evidence states the real path is POST /api/campaign-send-jobs with no /jobs/send sub-resource. The row asserted G4 and G4-fail at once. Restored to the audit gate in both score blocks."
   }
  },
  {
   "platform": "klaviyo",
   "capability": "template create",
   "tier": 2,
   "weight": 2,
   "gate": 0,
   "failing_gate": "G1",
   "vendor_endpoint": null,
   "api_version": "2024-10-15",
   "scopes_required": "templates:write",
   "scopes_requested": "none",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 0,
     "file": "lib/ads/writers/klaviyo.ts",
     "line": 1132,
     "snippet": "updateTemplate (PATCH) only; no POST /templates create"
    }
   ],
   "notes": "UNIMPLEMENTED (update-only)."
  },
  {
   "platform": "klaviyo",
   "capability": "flow create/update",
   "tier": 2,
   "weight": 2,
   "gate": 0,
   "failing_gate": "G1",
   "vendor_endpoint": null,
   "api_version": "2024-10-15",
   "scopes_required": "flows:write",
   "scopes_requested": "none",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 0,
     "file": "lib/ads/writers/klaviyo.ts",
     "line": 0,
     "snippet": "only status flip; no flow definition create/update"
    }
   ],
   "notes": "UNIMPLEMENTED (definition)."
  },
  {
   "platform": "klaviyo",
   "capability": "flow status change",
   "tier": 2,
   "weight": 2,
   "gate": 4,
   "failing_gate": "G5",
   "vendor_endpoint": "PATCH https://a.klaviyo.com/api/flows/{id}",
   "api_version": "2024-10-15 (STALE)",
   "scopes_required": "n/a (API key)",
   "scopes_requested": "none",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 1,
     "file": "lib/ads/writers/klaviyo.ts",
     "line": 204,
     "snippet": "PATCH flows/{id} {attributes:{status:draft|live}}"
    },
    {
     "gate": 5,
     "file": "lib/actions/reversibility.ts",
     "line": 53,
     "snippet": "pause<->resume reversible:full"
    }
   ],
   "notes": "[ADDENDUM correction (a): staleness cap G5->G4 — 2024-10-15 (STALE)] reaches G5; revision stale.",
   "audit_gate": 5,
   "revised": {
    "sprint": "unrecorded",
    "from": 5,
    "to": 4,
    "status": "stands",
    "why": "Demoted G5 to G4 with no annotation. No sprint, no date and no reason was recorded at the time; this stamp records only that the change happened and that its justification is unknown."
   }
  },
  {
   "platform": "klaviyo",
   "capability": "metric/event push",
   "tier": 3,
   "weight": 1,
   "gate": 0,
   "failing_gate": "G1",
   "vendor_endpoint": null,
   "api_version": "2024-10-15",
   "scopes_required": "events:write",
   "scopes_requested": "none",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 0,
     "file": "n/a",
     "line": 0,
     "snippet": "no event-push write verb"
    }
   ],
   "notes": "UNIMPLEMENTED."
  },
  {
   "platform": "klaviyo",
   "capability": "coupon code write",
   "tier": 3,
   "weight": 1,
   "gate": 0,
   "failing_gate": "G1",
   "vendor_endpoint": null,
   "api_version": "2024-10-15",
   "scopes_required": "coupons:write",
   "scopes_requested": "none",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 0,
     "file": "n/a",
     "line": 0,
     "snippet": "no coupon writer"
    }
   ],
   "notes": "UNIMPLEMENTED."
  },
  {
   "platform": "klaviyo",
   "capability": "back-in-stock subscribe",
   "tier": 3,
   "weight": 1,
   "gate": 0,
   "failing_gate": "G1",
   "vendor_endpoint": null,
   "api_version": "2024-10-15",
   "scopes_required": "subscriptions:write",
   "scopes_requested": "none",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 0,
     "file": "n/a",
     "line": 0,
     "snippet": "no back-in-stock writer"
    }
   ],
   "notes": "UNIMPLEMENTED."
  },
  {
   "platform": "klaviyo",
   "capability": "tag write",
   "tier": 3,
   "weight": 1,
   "gate": 0,
   "failing_gate": "G1",
   "vendor_endpoint": null,
   "api_version": "2024-10-15",
   "scopes_required": "tags:write",
   "scopes_requested": "none",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 0,
     "file": "n/a",
     "line": 0,
     "snippet": "no tag writer"
    }
   ],
   "notes": "UNIMPLEMENTED."
  },
  {
   "platform": "klaviyo",
   "capability": "webhook config",
   "tier": 3,
   "weight": 1,
   "gate": 0,
   "failing_gate": "G1",
   "vendor_endpoint": null,
   "api_version": "2024-10-15",
   "scopes_required": "webhooks:write",
   "scopes_requested": "none",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 0,
     "file": "n/a",
     "line": 0,
     "snippet": "no webhook writer"
    }
   ],
   "notes": "UNIMPLEMENTED."
  },
  {
   "platform": "tiktok",
   "capability": "campaign/ad group budget update",
   "tier": 1,
   "weight": 3,
   "gate": 4,
   "failing_gate": "G5",
   "vendor_endpoint": "POST https://business-api.tiktok.com/open_api/v1.3/{campaign|adgroup}/update/",
   "api_version": "v1.3",
   "scopes_required": "TikTok Ads Management (BC-app config)",
   "scopes_requested": "NONE in OAuth URL (BC-config model); persisted in grantedScopes",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 1,
     "file": "lib/ads/writers/tiktok.ts",
     "line": 108,
     "snippet": "tiktokApiPOST V(`${level}/update/`)"
    },
    {
     "gate": 4,
     "file": "lib/integrations/tiktok.ts",
     "line": 64,
     "snippet": "isOk = res.ok && json.code===0 — body-code parsed; budget major-unit decimal"
    },
    {
     "gate": 5,
     "file": "lib/ads/writers/tiktok.ts",
     "line": 32,
     "snippet": "preState:{} hardcoded -> budget 'rollback' has nothing to restore; daily-cap fails-open"
    }
   ],
   "notes": "RECONCILED G2->G4 (scope carried via BC-config+persisted; '1'-sentinel rubber-stamp readback = scope-drift finding, not G3 fail). Fails G5: preState={}, budget-mode guard is a no-op self-comparison."
  },
  {
   "platform": "tiktok",
   "capability": "status change (campaign/adgroup/ad)",
   "tier": 1,
   "weight": 3,
   "gate": 4,
   "failing_gate": "G5",
   "vendor_endpoint": "POST https://business-api.tiktok.com/open_api/v1.3/{level}/status/update/",
   "api_version": "v1.3",
   "scopes_required": "TikTok Ads Management",
   "scopes_requested": "NONE in URL; persisted",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 1,
     "file": "lib/ads/writers/tiktok.ts",
     "line": 62,
     "snippet": "status/update {operation_status:ENABLE|DISABLE}"
    },
    {
     "gate": 2,
     "file": "lib/actions/executeVerb.ts",
     "line": 813,
     "snippet": "register tiktok_pause_campaign/adgroup/ad + resume"
    }
   ],
   "notes": "IMPLEMENTED (refutes suspicion). inverse pairs reversible. RECONCILED G2->G4."
  },
  {
   "platform": "tiktok",
   "capability": "bid update",
   "tier": 1,
   "weight": 3,
   "gate": 4,
   "failing_gate": "G5",
   "vendor_endpoint": "POST https://business-api.tiktok.com/open_api/v1.3/adgroup/update/",
   "api_version": "v1.3",
   "scopes_required": "TikTok Ads Management",
   "scopes_requested": "NONE in URL; persisted",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 1,
     "file": "lib/ads/writers/tiktok.ts",
     "line": 128,
     "snippet": "adgroup/update {bid_price,bid_type}"
    },
    {
     "gate": 5,
     "file": "lib/ads/writers/tiktok.ts",
     "line": 32,
     "snippet": "preState={}; reversibility 'none'; no idempotency"
    }
   ],
   "notes": "validateBidGoal guards custom-bid vs REACH/VIDEO_VIEW. RECONCILED G2->G4."
  },
  {
   "platform": "tiktok",
   "capability": "campaign create",
   "tier": 2,
   "weight": 2,
   "gate": 4,
   "failing_gate": "G5",
   "vendor_endpoint": "POST https://business-api.tiktok.com/open_api/v1.3/campaign/create/",
   "api_version": "v1.3",
   "scopes_required": "TikTok Ads Management",
   "scopes_requested": "NONE in URL; persisted",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 1,
     "file": "lib/ads/writers/tiktok.ts",
     "line": 150,
     "snippet": "campaign/create {operation_status:DISABLE}"
    },
    {
     "gate": 3,
     "file": "lib/ads/writers/tiktok.ts",
     "line": 144,
     "snippet": "ONLY writer that pre-flights brandHasTikTokAdsScope — but rubber-stamped"
    }
   ],
   "notes": "lands DISABLED; idempotency findPrior. RECONCILED G2->G4."
  },
  {
   "platform": "tiktok",
   "capability": "ad group create w/ targeting",
   "tier": 2,
   "weight": 2,
   "gate": 4,
   "failing_gate": "G5",
   "vendor_endpoint": "POST https://business-api.tiktok.com/open_api/v1.3/adgroup/create/",
   "api_version": "v1.3",
   "scopes_required": "TikTok Ads Management",
   "scopes_requested": "NONE in URL; persisted",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 1,
     "file": "lib/ads/writers/tiktok.ts",
     "line": 179,
     "snippet": "adgroup/create location/age/gender/interest targeting DISABLE"
    }
   ],
   "notes": "CONVERT goal requires pixelId. RECONCILED G2->G4."
  },
  {
   "platform": "tiktok",
   "capability": "ad create",
   "tier": 2,
   "weight": 2,
   "gate": 4,
   "failing_gate": "G5",
   "vendor_endpoint": "POST https://business-api.tiktok.com/open_api/v1.3/ad/create/",
   "api_version": "v1.3",
   "scopes_required": "TikTok Ads Management",
   "scopes_requested": "NONE in URL; persisted",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 1,
     "file": "lib/ads/writers/tiktok.ts",
     "line": 204,
     "snippet": "ad/create creatives[{identity_id,video_id,ad_format:SINGLE_VIDEO}]"
    }
   ],
   "notes": "requires configured identity (READ, not created). RECONCILED G2->G4."
  },
  {
   "platform": "tiktok",
   "capability": "video/image asset upload",
   "tier": 2,
   "weight": 2,
   "gate": 4,
   "failing_gate": "G5",
   "vendor_endpoint": "POST https://business-api.tiktok.com/open_api/v1.3/file/{video|image}/ad/upload/",
   "api_version": "v1.3",
   "scopes_required": "TikTok Ads Management",
   "scopes_requested": "NONE in URL; persisted",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 1,
     "file": "lib/ads/writers/tiktok.ts",
     "line": 222,
     "snippet": "file/video/ad/upload UPLOAD_BY_URL"
    },
    {
     "gate": 5,
     "file": "lib/ads/writers/tiktok.ts",
     "line": 215,
     "snippet": "NO idempotency guard on upload -> re-fire DUPLICATES asset"
    }
   ],
   "notes": "URL-only (file upload deferred). RECONCILED G2->G4."
  },
  {
   "platform": "tiktok",
   "capability": "identity create",
   "tier": 2,
   "weight": 2,
   "gate": 0,
   "failing_gate": "G1",
   "vendor_endpoint": null,
   "api_version": null,
   "scopes_required": "TikTok Ads Management",
   "scopes_requested": "n/a",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 0,
     "file": "lib/ads/writers/tiktok.ts",
     "line": 243,
     "snippet": "readBrandTikTokIdentity READS BrandSettings; no /identity/create/ POST"
    }
   ],
   "notes": "UNIMPLEMENTED (DB-read only)."
  },
  {
   "platform": "tiktok",
   "capability": "custom audience create+upload",
   "tier": 3,
   "weight": 1,
   "gate": 0,
   "failing_gate": "G1",
   "vendor_endpoint": null,
   "api_version": null,
   "scopes_required": "TikTok DMP",
   "scopes_requested": "n/a",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 0,
     "file": "lib/ads/writers/tiktok.ts",
     "line": 0,
     "snippet": "no custom-audience writer"
    }
   ],
   "notes": "UNIMPLEMENTED."
  },
  {
   "platform": "tiktok",
   "capability": "lookalike create",
   "tier": 3,
   "weight": 1,
   "gate": 0,
   "failing_gate": "G1",
   "vendor_endpoint": null,
   "api_version": null,
   "scopes_required": "TikTok Ads Management",
   "scopes_requested": "n/a",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 0,
     "file": "lib/ads/writers/tiktok.ts",
     "line": 0,
     "snippet": "no lookalike writer"
    }
   ],
   "notes": "UNIMPLEMENTED."
  },
  {
   "platform": "tiktok",
   "capability": "pixel create",
   "tier": 3,
   "weight": 1,
   "gate": 0,
   "failing_gate": "G1",
   "vendor_endpoint": null,
   "api_version": null,
   "scopes_required": "TikTok Events Manager",
   "scopes_requested": "n/a",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 0,
     "file": "lib/ads/writers/tiktok-schemas.ts",
     "line": 98,
     "snippet": "pixelId only consumed as INPUT; no pixel/create writer"
    }
   ],
   "notes": "UNIMPLEMENTED."
  },
  {
   "platform": "tiktok",
   "capability": "events API server event send",
   "tier": 3,
   "weight": 1,
   "gate": 0,
   "failing_gate": "G1",
   "vendor_endpoint": null,
   "api_version": null,
   "scopes_required": "TikTok Events API token",
   "scopes_requested": "n/a",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 0,
     "file": "lib/ads/writers/tiktok.ts",
     "line": 0,
     "snippet": "no event/track/ writer"
    }
   ],
   "notes": "UNIMPLEMENTED."
  },
  {
   "platform": "tiktok",
   "capability": "catalog & DPA wiring",
   "tier": 3,
   "weight": 1,
   "gate": 0,
   "failing_gate": "G1",
   "vendor_endpoint": null,
   "api_version": null,
   "scopes_required": "TikTok Catalog",
   "scopes_requested": "n/a",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 0,
     "file": "lib/ads/writers/tiktok.ts",
     "line": 0,
     "snippet": "no catalog/DPA writer"
    }
   ],
   "notes": "UNIMPLEMENTED."
  },
  {
   "platform": "ga4",
   "capability": "key event / conversion event create",
   "tier": 1,
   "weight": 3,
   "gate": 4,
   "failing_gate": "G5",
   "vendor_endpoint": "analyticsadmin.googleapis.com v1beta properties/{id}/keyEvents (googleapis SDK)",
   "api_version": "v1beta",
   "scopes_required": "analytics.edit",
   "scopes_requested": "analytics.readonly,analytics.edit",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 1,
     "file": "lib/analytics/ga4-admin.ts",
     "line": 128,
     "snippet": "properties.keyEvents.create({eventName})"
    },
    {
     "gate": 3,
     "file": "lib/analytics/ga4-admin.ts",
     "line": 49,
     "snippet": "grantedScopes includes /auth/analytics.edit — FAIL-CLOSED gate"
    },
    {
     "gate": 5,
     "file": "lib/analytics/ga4-admin.ts",
     "line": 123,
     "snippet": "preState={}; no idempotency; reversible:none"
    }
   ],
   "notes": "REAL SDK write, shadow-gated. Scope readback fail-closed (analytics.edit callback drift is NOT a bug). Fails G5 on preState/idempotency."
  },
  {
   "platform": "ga4",
   "capability": "custom dimension create",
   "tier": 1,
   "weight": 3,
   "gate": 4,
   "failing_gate": "G5",
   "vendor_endpoint": "analyticsadmin.googleapis.com v1beta properties/{id}/customDimensions (SDK)",
   "api_version": "v1beta",
   "scopes_required": "analytics.edit",
   "scopes_requested": "analytics.readonly,analytics.edit",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 1,
     "file": "lib/analytics/ga4-admin.ts",
     "line": 112,
     "snippet": "customDimensions.create({parameterName,scope})"
    }
   ],
   "notes": "archive-only correct. Fails G5 (preState={})."
  },
  {
   "platform": "ga4",
   "capability": "custom metric create",
   "tier": 1,
   "weight": 3,
   "gate": 0,
   "failing_gate": "G1",
   "vendor_endpoint": null,
   "api_version": null,
   "scopes_required": "analytics.edit",
   "scopes_requested": "analytics.readonly,analytics.edit",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 0,
     "file": "repo-wide grep",
     "line": 0,
     "snippet": "grep customMetrics: NO matches"
    }
   ],
   "notes": "ABSENT."
  },
  {
   "platform": "ga4",
   "capability": "audience create",
   "tier": 2,
   "weight": 2,
   "gate": 4,
   "failing_gate": "G5",
   "vendor_endpoint": "analyticsadmin.googleapis.com v1alpha properties/{id}/audiences (SDK)",
   "api_version": "v1alpha",
   "scopes_required": "analytics.edit",
   "scopes_requested": "analytics.readonly,analytics.edit",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 1,
     "file": "lib/analytics/ga4-admin.ts",
     "line": 95,
     "snippet": "audiences.create({filterClauses,membershipDurationDays})"
    }
   ],
   "notes": "v1alpha untyped (cast as never). Fails G5."
  },
  {
   "platform": "ga4",
   "capability": "data stream create/update",
   "tier": 2,
   "weight": 2,
   "gate": 0,
   "failing_gate": "G1",
   "vendor_endpoint": null,
   "api_version": null,
   "scopes_required": "analytics.edit",
   "scopes_requested": "analytics.readonly,analytics.edit",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 0,
     "file": "repo-wide grep",
     "line": 0,
     "snippet": "grep dataStreams: NO matches"
    }
   ],
   "notes": "ABSENT."
  },
  {
   "platform": "ga4",
   "capability": "measurement protocol event send",
   "tier": 2,
   "weight": 2,
   "gate": 0,
   "failing_gate": "G1",
   "vendor_endpoint": null,
   "api_version": null,
   "scopes_required": "mp measurement_id+api_secret",
   "scopes_requested": "n/a",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 0,
     "file": "repo-wide grep",
     "line": 0,
     "snippet": "grep mp/collect|measurement_id|api_secret: NO matches"
    }
   ],
   "notes": "ABSENT (Meta CAPI exists; GA4 MP does not)."
  },
  {
   "platform": "ga4",
   "capability": "Google Ads link create",
   "tier": 2,
   "weight": 2,
   "gate": 0,
   "failing_gate": "G1",
   "vendor_endpoint": null,
   "api_version": null,
   "scopes_required": "analytics.edit",
   "scopes_requested": "analytics.readonly,analytics.edit",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 0,
     "file": "repo-wide grep",
     "line": 0,
     "snippet": "grep googleAdsLinks: NO matches"
    }
   ],
   "notes": "ABSENT."
  },
  {
   "platform": "ga4",
   "capability": "enhanced measurement settings",
   "tier": 2,
   "weight": 2,
   "gate": 0,
   "failing_gate": "G1",
   "vendor_endpoint": null,
   "api_version": null,
   "scopes_required": "analytics.edit",
   "scopes_requested": "analytics.readonly,analytics.edit",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 0,
     "file": "repo-wide grep",
     "line": 0,
     "snippet": "grep enhancedMeasurementSettings: NO matches"
    }
   ],
   "notes": "ABSENT."
  },
  {
   "platform": "ga4",
   "capability": "property settings",
   "tier": 3,
   "weight": 1,
   "gate": 0,
   "failing_gate": "G1",
   "vendor_endpoint": "analyticsadmin v1beta accountSummaries (GET, read-only)",
   "api_version": "v1beta",
   "scopes_required": "analytics.edit",
   "scopes_requested": "analytics.readonly,analytics.edit",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 0,
     "file": "app/api/integrations/google-analytics/properties/route.ts",
     "line": 63,
     "snippet": "read-only GET accountSummaries diagnostic"
    }
   ],
   "notes": "read-diagnostic only, no write."
  },
  {
   "platform": "ga4",
   "capability": "data retention",
   "tier": 3,
   "weight": 1,
   "gate": 0,
   "failing_gate": "G1",
   "vendor_endpoint": null,
   "api_version": null,
   "scopes_required": "analytics.edit",
   "scopes_requested": "analytics.readonly,analytics.edit",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 0,
     "file": "repo-wide grep",
     "line": 0,
     "snippet": "GA4 dataRetentionSettings absent"
    }
   ],
   "notes": "ABSENT."
  },
  {
   "platform": "ga4",
   "capability": "attribution settings",
   "tier": 3,
   "weight": 1,
   "gate": 0,
   "failing_gate": "G1",
   "vendor_endpoint": null,
   "api_version": null,
   "scopes_required": "analytics.edit",
   "scopes_requested": "analytics.readonly,analytics.edit",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 0,
     "file": "app/dashboard/[brandId]/settings/attribution/page.tsx",
     "line": 11,
     "snippet": "internal Brand attribution config, NOT GA4 Admin attributionSettings API"
    }
   ],
   "notes": "ABSENT (GA4 Admin)."
  },
  {
   "platform": "ga4",
   "capability": "BigQuery link",
   "tier": 3,
   "weight": 1,
   "gate": 0,
   "failing_gate": "G1",
   "vendor_endpoint": null,
   "api_version": null,
   "scopes_required": "analytics.edit",
   "scopes_requested": "analytics.readonly,analytics.edit",
   "proof_type": "none",
   "last_success_at": null,
   "evidence": [
    {
     "gate": 0,
     "file": "repo-wide grep",
     "line": 0,
     "snippet": "grep bigQueryLinks: NO matches"
    }
   ],
   "notes": "ABSENT."
  }
 ]
}