{
  "_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,
        "plausible_G4plus": 0.566,
        "maturity": 0.452,
        "histogram": {
          "G0": 63,
          "G1": 2,
          "G2": 0,
          "G3": 1,
          "G4": 17,
          "G5": 47,
          "G6": 0
        }
      },
      "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
          }
        }
      }
    },
    "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"
      }
    }
  },
  "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)."
    },
    {
      "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)."
    },
    {
      "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."
    },
    {
      "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."
    },
    {
      "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)."
    },
    {
      "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 / 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)."
    },
    {
      "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."
    },
    {
      "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."
    },
    {
      "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."
    },
    {
      "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": 4,
      "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."
    },
    {
      "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."
    },
    {
      "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."
    }
  ]
}