On February 26–27, 2026, three unrelated events — a corporate lawsuit in São Paulo, a legislative surge across US state capitals, and a policy symposium in Washington, D.C. — converged on the same structural truth: the world is building accountability infrastructure for what AI creates, but still has no way to verify what AI refused to create. This article fact-checks each event against primary sources, identifies what each gets right and wrong, maps the technical gap they share, and provides the cryptographic implementation that fills it.
TL;DR
Meta sued deepfake advertisers from Brazil, China, and Vietnam — but its legal defense rests entirely on internal logs that no external party can verify. At least five US states filed bills requiring "provenance data" for AI-generated content — but every bill addresses only content that exists, not content that was blocked. The Cato Institute hosted a Section 230 symposium where panelists warned that stripping liability protection from generative AI output would create a new accountability burden — with no technical infrastructure to meet it.
All three stories share one structural blind spot: they assume AI providers can prove their safety claims, but no mechanism exists for independent verification of what AI refused to generate.
This article:
- Fact-checks each event against primary sources (with corrections where needed)
- Maps the technical gap using CAP-SRP's Completeness Invariant
- Provides working Python code for building cryptographic refusal logs
- Shows how provenance legislation and refusal provenance form complementary layers
GitHub: veritaschain/cap-spec · License: CC BY 4.0
Table of Contents
- Event 1: Meta Sues Deepfake Scammers — But Can't Prove What It Blocked
- Event 2: US States File Provenance Bills — For Content That Exists
- Event 3: Section 230 at 30 — AI Liability Without AI Accountability Infrastructure
- The Pattern: Three Events, One Verification Gap
- The Completeness Invariant: From "Trust Us" to "Verify This"
- Building the Refusal Log: Implementation
- Provenance Legislation + Refusal Provenance: The Full Stack
- What This Means for Developers
- Transparency Notes
Event 1: Meta Sues Deepfake Scammers — But Can't Prove What It Blocked
What happened
On February 26, 2026, Meta announced four lawsuits targeting scam advertisers who used deepfake images and audio of celebrities — including medical professionals — to promote fraudulent health products and investment schemes on Facebook and Instagram.
The lawsuits target operations across multiple countries. Among the named defendants: advertisers in Brazil who created deepfake content impersonating physicians to sell unauthorized medical products, and operations in China running ad-fraud schemes that exploited celebrity likenesses. Meta described the defendants as using "increasingly sophisticated technology, including generative AI" to bypass platform safeguards.
Dr. Drauzio Varella — one of Brazil's most recognized physicians, an oncologist at Hospital do Câncer and a household name through his Globo TV health programs — was directly victimized. His deepfake likeness was used to endorse unregulated health products. In comments to Brazilian media, Varella called these schemes a drop in an ocean of fraud against public health, and described platforms as partners in the fraud through the reach they provide — a notably stronger characterization than much of the English-language reporting conveyed.
Fact-check verdict: ✅ Core event confirmed, with corrections needed
Confirmed. Meta's own blog post (dated February 26, 2026) announces the lawsuits. The event was independently covered by AFP wire service, Hong Kong Free Press, Arab News, Engadget, Bloomberg, and dozens of other outlets.
Correction 1: Three countries, not two. The original claim states defendants were from "Brazil and China." In fact, Meta's four lawsuits target defendants from Brazil, China, and Vietnam. The fourth defendant, Lý Văn Lâm, operated a Vietnamese cloaking and subscription fraud ring involving counterfeit luxury brand ads. Omitting Vietnam understates the geographic scope of Meta's enforcement.
Correction 2: Varella's language was stronger than reported. English-language coverage softened his remarks. His Portuguese statements to O Globo used "sócios da fraude" — literally "partners in the fraud" — not merely "complicit through reach." The distinction matters: "partner" implies active facilitation, not passive negligence. The "drop in the ocean" quote is accurate ("uma gota d'água em um oceano de estelionato contra a saúde pública").
Correction 3: Varella is an oncologist but his expertise is broader. His Wikipedia page and Hospital das Clínicas CV confirm training at MD Anderson and Memorial Sloan Kettering Cancer Centers, but his public profile spans infectious disease (particularly HIV/AIDS education during Brazil's epidemic response), public health advocacy, and general medical communication. Describing him solely as "a prominent oncologist" is reductive.
Source verification:
| Source | Status | Notes |
|---|---|---|
| Meta blog (primary) | ✅ Live | about.fb.com/news/2026/02/meta-takes-legal-action-against-scam-advertisers/ |
| Straits Times (claimed [1]) | ⚠️ Unconfirmed slug | ST carries AFP wire; may exist under different URL |
| TechBuzz.ai [8] | ✅ Live | Smaller publication; confirms core claims |
| Hong Kong Free Press | ✅ Live | AFP wire pickup with full details |
| Arab News | ✅ Live | Confirms three-country scope |
The verification gap Meta's lawsuit exposes
Here's the critical technical question this lawsuit raises — and it's one Meta's legal team cannot answer with current infrastructure.
Meta's defense is built on four claims:
- We detected the fraudulent content
- We removed it and banned the accounts
- We blocked payment processing
- We pursued legal action
Claims 1, 2, 3, and 4 are all retrospective actions on content that existed. What Meta cannot demonstrate — and what no external party can verify — is:
- How many deepfake ads were submitted but automatically blocked before reaching users?
- What percentage of generation attempts using Meta's own AI tools (Imagine, Meta AI) were refused for policy violations?
- Were the scammers' accounts ever used with Meta's internal generative tools, and if so, what was the refusal rate?
- Is Meta's claim of proactive enforcement complete, or were there periods where safeguards were reduced, disabled, or circumvented?
The current evidentiary model:
Meta's Legal Position (Trust-Us Model)
══════════════════════════════════════
Scammer uploads deepfake ad ──→ [Meta Ad Review System]
│
┌─────────┴──────────┐
▼ ▼
Approved Rejected
│ │
▼ ▼
Internal DB Internal DB
(mutable) (mutable)
│ │
▼ ▼
"We eventually "We say we
removed this" blocked some"
│ │
└─────────┬───────────┘
▼
Court asks:
"How many did you block
before they went live?"
│
▼
Meta: "Our internal data
shows we blocked X%."
Court: "Can we independently
verify that number?"
Meta: "...you'd have to
trust our logs."
Varella's characterization — platforms as "sócios da fraude" — carries a specific legal implication in Brazilian law. If Meta is characterized as a partner rather than a passive intermediary, the burden shifts: Meta would need to prove it took all reasonable preventive measures, not just reactive ones. That proof requires something more than internal logs.
Event 2: US States File Provenance Bills — For Content That Exists
What happened
The Transparency Coalition AI — a verified 501(c)(3) nonprofit (EIN 99-2618608) based in Bellevue, Washington — published its weekly AI Legislative Update covering a surge in state-level bills requiring provenance data for AI-generated content.
The most CAP-SRP-relevant bills filed or progressing during this period:
Arizona SB 1786 — Requires provenance data for AI-generated video, image, and audio content. Listed as "New this week" in the Transparency Coalition tracker. Sponsored by Senator Petersen.
Illinois SB 3263 ("AI Provenance Data Act") and HB 4711 ("Provenance Data Requirements Act") — Companion bills establishing comprehensive provenance data requirements for AI-generated content at the state level.
New York A 6540 / S 6954 — Companion bills (Assemblymember Bores, Senator Gounardes) requiring synthetic content creation system providers to embed provenance data in generated or modified content.
New York A 6578 / S 6955 ("Artificial Intelligence Training Data Transparency Act") — Companion bills requiring AI developers to disclose training data sources. A 6578 passed the New York Assembly on June 10, 2025.
Additionally, multiple states are simultaneously advancing chatbot safety laws, CSAM/deepfake criminalization, and AI training data transparency requirements.
Fact-check verdict: ✅ All bill numbers and titles verified
This is the cleanest of the three items. Every bill number is real, every cited title matches exactly, and the Transparency Coalition is a legitimate organization.
Verification via LegiScan and state legislature databases:
| Bill | Title | Status | Verified? |
|---|---|---|---|
| AZ SB 1786 | Provenance data; AI-generated content | Filed | ✅ |
| IL SB 3263 | AI Provenance Data Act | Filed | ✅ |
| IL HB 4711 | Provenance Data Requirements Act | Filed | ✅ |
| NY A 6540 / S 6954 | Synthetic content provenance | Filed | ✅ |
| NY A 6578 / S 6955 | AI Training Data Transparency Act | A 6578 passed Assembly | ✅ |
Minor timing note: The Transparency Coalition update was published with a February 27 URL slug, but some of these bills (Arizona SB 1786 in particular) first appeared in the February 20, 2026 update. The article correctly identifies them as being in active legislative motion during the week of February 24–28.
Organizational verification: The Transparency Coalition AI was founded in 2024 by Rob Eleveld and Jai Jaisimha, registered as a 501(c)(3), and maintains a comprehensive real-time legislative tracker. This is an established, legitimate policy tracking organization — not a fabricated source.
What these bills require — and what they don't
Let's examine the actual legislative language and map exactly where it overlaps with (and diverges from) verifiable refusal provenance.
Every bill in this cohort addresses the same core requirement:
What State Provenance Bills Mandate
════════════════════════════════════
AI-Generated Content ──→ [Provenance Metadata]
│ │
│ ├─ Who created it (generator ID)
│ ├─ When it was created (timestamp)
│ ├─ What tool/model was used
│ ├─ Whether it was modified
│ └─ Machine-readable identifier
│
▼
Content exists ──→ Metadata exists ──→ Verifiable
This is conceptually aligned with the C2PA Content Credentials model. The bill language maps almost directly to C2PA manifest fields:
| Bill Requirement | C2PA Equivalent |
|---|---|
| Generator identification |
claim_generator field |
| Creation timestamp |
dc:created assertion |
| Modification history |
c2pa.ingredient + c2pa.action
|
| Machine-readable format | JUMBF container / CBOR manifest |
| Persistence requirement | C2PA hard binding via hash |
This is real progress. The fact that state legislatures are codifying "provenance data" as a legal obligation creates regulatory infrastructure that did not exist a year ago. The political consensus for cryptographically verifiable traceability is forming.
But notice what's missing from every single bill:
What State Provenance Bills Do NOT Address
═══════════════════════════════════════════
User submits prompt ──→ [AI Safety System]
│
┌─────────┴──────────┐
▼ ▼
Generated REFUSED
│ │
▼ ▼
✅ Provenance ❌ No provenance
metadata exists No metadata
Bill requirements No legal requirement
satisfied No audit trail
No external verification
No proof it happened
═══════════════════════════════════════════
The bills create accountability for OUTPUT.
They create ZERO accountability for REFUSAL.
═══════════════════════════════════════════
No bill in this cohort requires providers to:
- Log that a generation request was received
- Record that a safety evaluation denied a request
- Prove that the total count of attempts matches the total count of outcomes
- Make refusal logs available for independent audit
- Anchor refusal events to external timestamps
The result is a one-sided accountability structure. Providers must prove what they created — which they already want to do, since it's the product they're selling. They are under no obligation to prove what they refused to create — which is precisely where the safety claims live.
The stack that doesn't yet exist
This creates a clear architectural picture of the provenance landscape as of February 2026:
US State AI Provenance Legislation Stack
═════════════════════════════════════════
Layer 4: TRAINING DATA TRANSPARENCY
┌─────────────────────────────────────┐
│ NY A 6578 / S 6955 │
│ "What data trained the model?" │
│ Status: A 6578 passed Assembly │
└─────────────────────────────────────┘
Layer 3: CONTENT PROVENANCE
┌─────────────────────────────────────┐
│ AZ SB 1786, IL SB 3263 / HB 4711, │
│ NY A 6540 / S 6954 │
│ "What content was generated and │
│ by what tool?" │
│ Status: Multiple bills filed/active │
└─────────────────────────────────────┘
Layer 2: CONTENT LABELING
┌─────────────────────────────────────┐
│ Various state labeling requirements │
│ "Is this AI-generated?" │
│ Status: Several enacted │
└─────────────────────────────────────┘
Layer 1: HARMFUL CONTENT PENALTIES
┌─────────────────────────────────────┐
│ Deepfake criminalization (WA, PA, │
│ CA, multiple others) │
│ "Did someone create harmful AI │
│ content?" │
│ Status: Enforcing │
└─────────────────────────────────────┘
╔═════════════════════════════════════╗
║ ░░░ MISSING LAYER ░░░░░░░░░░░░░░ ║
║ ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ║
║ ░ REFUSAL PROVENANCE ║
║ ░ "What did the AI REFUSE to ║
║ ░ generate, and can you prove ║
║ ░ the refusal log is complete?" ║
║ ░ Status: No bill addresses this ║
║ ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ║
╚═════════════════════════════════════╝
The legislative trajectory is clear: provenance requirements are expanding upward through the stack. Training data transparency (Layer 4) is the most recent addition. Refusal provenance is the next logical layer — and the one most directly relevant to the Meta lawsuit and Section 230 debate.
Event 3: Section 230 at 30 — AI Liability Without AI Accountability Infrastructure
What happened
The Cato Institute hosted a symposium marking the 30th anniversary of Section 230 of the Communications Decency Act, with generative AI emerging as the dominant point of contention.
Section 230 was signed into law by President Clinton on February 8, 1996, as Title V of the Telecommunications Act of 1996. The 30th anniversary math is exact.
The key panelist: Jess Miers, an assistant professor at the University of Akron School of Law's Center for Intellectual Property and Technology with extensive background in Section 230 scholarship (including a TED talk and prior roles at Google and Chamber of Progress). Miers warned that categorically denying Section 230 protection to generative AI output could have cascading consequences:
"Those are classically protected activities under Section 230. If we just arrive at the blanket case that Section 230 does not apply to generative AI, then I think all of those activities start to fall out the window."
Her concern: ranking, sorting, editing, and recommendation functions — which have been protected by Section 230 for decades — all use algorithmic processes that could be recharacterized as "generative AI" output. A blanket exclusion would destabilize the entire liability framework.
Other panelists raised the startup dimension: if AI-generated output carries direct publisher liability, only companies with massive legal departments can afford to deploy generative features. Senator Ron Wyden, one of Section 230's original authors, discussed the provision's startup-protection intent.
Fact-check verdict: ✅ Fully confirmed
The symposium is verified through Cato Institute's own event page, reporting by Medill on the Hill (Northwestern University's student journalism program), SiliconANGLE, and multiple social media accounts of attendees.
Detailed verification:
| Claim | Status | Source |
|---|---|---|
| Cato hosted the symposium | ✅ | Cato event page, multiple reports |
| Section 230 signed Feb 8, 1996 | ✅ | Congressional Record, CDA legislative history |
| 30th anniversary in Feb 2026 | ✅ | Arithmetic confirmed |
| Jess Miers, Akron Law | ✅ | University faculty directory, personal site, Cato event page |
| Miers' quote on protected activities | ✅ | Verbatim in SiliconANGLE article |
| Startup entry barrier concern | ✅ Thematic | Fair characterization; no single direct quote uses this phrase |
| Senator Wyden participated | ✅ | Multiple reports confirm |
Minor nuance on Miers' title: Some university pages list her as "Visiting Assistant Professor." Both the Cato event page and her own profiles omit "Visiting." This is a common academic distinction — visiting positions are typically fixed-term — but doesn't affect the substance of her arguments.
SiliconANGLE URL [15]: ✅ Live and confirmed at siliconangle.com/2026/02/27/internet-fire-will-section-230-live-see-another-birthday/. The article by Duncan Riley provides detailed coverage including multiple direct quotes from panelists.
Medill on the Hill URL [3]: ✅ Live and confirmed at the claimed URL. Northwestern's Medill School of Journalism student publication.
Why this matters for AI system developers
The Section 230 debate creates a direct feedback loop to technical infrastructure requirements. Here's the logic chain:
Section 230 Erosion → AI Liability Chain
═════════════════════════════════════════
Step 1: Courts/Congress narrow Section 230 for AI output
│
▼
Step 2: AI providers become directly liable for outputs
(no intermediary shield)
│
▼
Step 3: Liability creates legal discovery obligations
"Show us everything the model generated AND
everything it refused to generate"
│
▼
Step 4: Providers must PROVE safety measures worked
(not just assert they exist)
│
▼
Step 5: Internal logs are insufficient
- Mutable (can be altered after the fact)
- Incomplete (no completeness guarantee)
- Unverifiable (no external anchoring)
│
▼
Step 6: Providers need CRYPTOGRAPHIC evidence
- Tamper-evident event logs
- External timestamps
- Completeness proofs
- Third-party verifiable
│
▼
Step 7: This is exactly what CAP-SRP provides
Miers' specific concern — that algorithmic ranking and sorting could be swept into generative AI liability — has a direct technical implication. If courts need to determine "where does the algorithm end and the generation begin?", the answer requires a precise record of the decision boundary. CAP-SRP's event model provides exactly this: a GEN_ATTEMPT marks the moment a generation request enters the system, and the subsequent GEN, GEN_DENY, or GEN_ERROR marks the system's decision. The boundary is cryptographically recorded.
The current state of the debate — as both the Medill and SiliconANGLE coverage make clear — is that everyone agrees the question is important, but nobody has proposed the technical infrastructure to answer it. The discussion remains entirely in the policy domain.
What the Section 230 Debate Is Missing
═══════════════════════════════════════
Policy Question:
"Should AI output be protected by Section 230?"
Missing Technical Questions:
├─ "Can the provider prove what the model
│ generated vs. what a user modified?"
├─ "Can the provider prove what it refused
│ to generate?"
├─ "Is there a complete, tamper-evident log
│ of all generation decisions?"
└─ "Can a court independently verify
these claims without trusting the
provider's internal systems?"
Without answers to the technical questions,
the policy question is unresolvable —
regardless of where Section 230 lands.
The Pattern: Three Events, One Verification Gap
Map these three events against the AI accountability landscape and a clear pattern emerges:
Three Events, One Gap (February 26-27, 2026)
═════════════════════════════════════════════
Event 1: Meta Deepfake Lawsuit
┌────────────────────────────────────────────┐
│ What Meta CAN prove: │
│ ✅ "We removed this content" │
│ ✅ "We banned these accounts" │
│ ✅ "We stopped these payments" │
│ │
│ What Meta CANNOT prove: │
│ ❌ "We blocked X% of deepfake attempts" │
│ ❌ "Our safety filter was active 100% │
│ of the time" │
│ ❌ "No deepfake ads slipped through │
│ during this window" │
│ ❌ "Here's a complete, verifiable audit │
│ trail of every ad review decision" │
└────────────────────────────────────────────┘
Event 2: State Provenance Legislation
┌────────────────────────────────────────────┐
│ What the bills REQUIRE: │
│ ✅ "Label AI-generated content" │
│ ✅ "Embed provenance metadata" │
│ ✅ "Identify the generating tool" │
│ │
│ What the bills DO NOT require: │
│ ❌ "Log refused generation attempts" │
│ ❌ "Prove refusal logs are complete" │
│ ❌ "Enable external verification of │
│ safety system operation" │
│ ❌ "Anchor refusal records to external │
│ timestamps" │
└────────────────────────────────────────────┘
Event 3: Section 230 Symposium
┌────────────────────────────────────────────┐
│ What the debate ESTABLISHES: │
│ ✅ AI providers may lose intermediary │
│ protection │
│ ✅ Liability requires provable safety │
│ measures │
│ ✅ The decision boundary matters legally │
│ │
│ What the debate LACKS: │
│ ❌ Technical proposal for proving safety │
│ ❌ Standard for logging AI decisions │
│ ❌ Framework for external verification │
│ ❌ Implementation path for providers │
└────────────────────────────────────────────┘
Common denominator:
══════════════════
All three assume AI providers can demonstrate
their safety claims. None provides the
technical infrastructure for doing so.
The negative evidence problem, concretely
Each event illustrates a different face of the same underlying problem — what CAP-SRP calls the negative evidence problem:
Meta's lawsuit → "We blocked harmful content" → Can you prove the number of blocks? Can you prove the log is complete? Can a court verify this without trusting your internal database?
State provenance bills → "AI content must carry provenance" → What about the content that was never created? The dangerous prompts that were refused? Those leave no provenance trail because they produced no artifact.
Section 230 debate → "AI providers should be accountable" → Accountable for what they generate? For what they refuse? For the completeness of their decision-making? None of these can be verified with current infrastructure.
The common thread: you cannot audit what you cannot observe, and you cannot observe refusals without a system designed to record them.
The Completeness Invariant: From "Trust Us" to "Verify This"
The CAP-SRP specification addresses this gap through a single mathematical guarantee:
Completeness Invariant:
∑ GEN_ATTEMPT = ∑ GEN + ∑ GEN_DENY + ∑ GEN_ERROR
For any time window, the count of attempts
MUST exactly equal the count of all outcomes.
The critical architectural insight: GEN_ATTEMPT is logged BEFORE the safety evaluation runs. This creates an unforgeable commitment that a request existed, regardless of what follows.
Event Flow
══════════
┌──────────────────┐
│ Request │
│ Received │
└────────┬─────────┘
│
▼
┌──────────────────┐
│ GEN_ATTEMPT │ ← Logged FIRST (before any evaluation)
│ ──────────── │
│ EventID: uuid7 │ Signed with Ed25519
│ PromptHash: │ Chained to previous event
│ sha256(prompt) │ Added to Merkle tree
│ Timestamp: now │
│ PrevHash: ... │
└────────┬─────────┘
│
▼
┌──────────────────┐
│ Safety Evaluator │ ← Your existing safety system
│ (unchanged) │ No modifications required
└────────┬─────────┘
│
┌───────┼───────┐
▼ ▼ ▼
┌──────┐┌──────┐┌──────┐
│ GEN ││DENY ││ERROR │
│ ││ ││ │
│Linked││Linked││Linked│
│to ││to ││to │
│ATTEMPT│ATTEMPT│ATTEMPT│
└──────┘└──────┘└──────┘
│ │ │
└───────┴───────┘
│
▼
Completeness Check:
attempts == outcomes?
✓ → audit trail valid
✗ → integrity violation
Why this matters more than "better logging"
Traditional logging can record the same events. The difference is in the threat model. CAP-SRP assumes the AI provider may have incentives to underreport failures, fabricate refusals, or selectively omit events. The cryptographic countermeasures:
| Threat | Attack | CAP-SRP Mitigation |
|---|---|---|
| Selective logging | Log only favorable outcomes | Completeness Invariant — gaps are detectable |
| Log modification | Alter historical records | SHA-256 hash chain — any change breaks the chain |
| Backdating | Create records with false timestamps | RFC 3161 external anchoring via independent TSA |
| Split-view | Show different logs to different auditors | Merkle tree — single root, inclusion proofs |
| Fabrication | Create false refusal records | Attempt-outcome pairing with pre-commitment |
Applying the invariant to each event
For Meta's lawsuit: If Meta maintained CAP-SRP-compliant logs, a court could request the Evidence Pack for the time period in question. The Completeness Invariant would show: during February 1–26, 2026, there were X ad review attempts, Y approvals, Z denials, and W errors — and X = Y + Z + W. The court could verify the Merkle root against external timestamps. Meta's claim of proactive enforcement becomes verifiable math, not self-attestation.
For state provenance bills: CAP-SRP is the missing layer. The bills mandate provenance for generated content (GEN events). CAP-SRP provides provenance for refused content (GEN_DENY events) and the completeness guarantee that ties them together. The two are complementary:
Complete Provenance Stack
═════════════════════════
State Provenance Bills CAP-SRP
(content that exists) (decisions about all content)
───────────────────── ──────────────────────────
C2PA manifest on GEN_ATTEMPT logged for
generated image ←──→ every request
Content Credentials GEN_DENY logged for
with tool/model ID every refusal
Provenance metadata Completeness Invariant
embedded in file proves log is complete
External anchoring
proves timestamps
For the Section 230 debate: If providers lose intermediary protection, CAP-SRP becomes their primary technical defense. A provider could demonstrate: "Our system received 10 million generation requests this month. 9.5 million were generated (with C2PA provenance). 480,000 were denied for safety reasons (with cryptographic refusal logs). 20,000 resulted in errors. 10,000,000 = 9,500,000 + 480,000 + 20,000. Here's the Merkle root, externally timestamped by an independent TSA. Verify it."
Building the Refusal Log: Implementation
Here's a working Python implementation of the core CAP-SRP event logging system. This is a sidecar — it sits alongside your existing AI pipeline without modifying it.
Event Core
import hashlib
import json
import time
import uuid
import base64
from dataclasses import dataclass, field, asdict
from typing import Optional, List, Dict
from enum import Enum
from cryptography.hazmat.primitives.asymmetric.ed25519 import (
Ed25519PrivateKey, Ed25519PublicKey
)
class EventType(Enum):
GEN_ATTEMPT = "GEN_ATTEMPT"
GEN = "GEN"
GEN_DENY = "GEN_DENY"
GEN_ERROR = "GEN_ERROR"
class RiskCategory(Enum):
NCII_RISK = "NCII_RISK"
CSAM_RISK = "CSAM_RISK"
VIOLENCE_EXTREME = "VIOLENCE_EXTREME"
HATE_CONTENT = "HATE_CONTENT"
COPYRIGHT_VIOLATION = "COPYRIGHT_VIOLATION"
DEEPFAKE_CELEBRITY = "DEEPFAKE_CELEBRITY" # ← Relevant to Meta case
FRAUDULENT_ENDORSEMENT = "FRAUDULENT_ENDORSEMENT" # ← Relevant to Meta case
CONTENT_POLICY = "CONTENT_POLICY"
def sha256(data: str) -> str:
"""Compute SHA-256 hash with prefix."""
return f"sha256:{hashlib.sha256(data.encode()).hexdigest()}"
def canonicalize(obj: dict) -> str:
"""RFC 8785 JSON Canonicalization (simplified)."""
return json.dumps(obj, sort_keys=True, separators=(",", ":"))
def uuid7() -> str:
"""Generate UUIDv7 (time-ordered) for event IDs."""
timestamp_ms = int(time.time() * 1000)
rand_bits = uuid.uuid4().int & ((1 << 62) - 1)
uuid_int = (timestamp_ms << 80) | (0x7 << 76) | rand_bits
return str(uuid.UUID(int=uuid_int & ((1 << 128) - 1)))
@dataclass
class CAPEvent:
"""Base CAP-SRP event with cryptographic integrity."""
event_id: str
event_type: EventType
chain_id: str
timestamp: str
prev_hash: Optional[str]
event_hash: Optional[str] = None
signature: Optional[str] = None
def compute_hash(self) -> str:
data = {k: v for k, v in asdict(self).items()
if k not in ("event_hash", "signature")}
data["event_type"] = self.event_type.value
return sha256(canonicalize(data))
def sign(self, private_key: Ed25519PrivateKey):
self.event_hash = self.compute_hash()
hash_bytes = bytes.fromhex(self.event_hash[7:])
sig = private_key.sign(hash_bytes)
self.signature = f"ed25519:{base64.b64encode(sig).decode()}"
@dataclass
class GenAttemptEvent(CAPEvent):
"""Logged BEFORE safety evaluation. Creates unforgeable commitment."""
prompt_hash: str = ""
input_type: str = "text"
model_version: str = ""
policy_id: str = ""
actor_hash: str = ""
@classmethod
def create(cls, chain_id, prev_hash, prompt, actor_id,
model_version, policy_id, input_type="text"):
return cls(
event_id=uuid7(),
event_type=EventType.GEN_ATTEMPT,
chain_id=chain_id,
timestamp=time.strftime("%Y-%m-%dT%H:%M:%S.000Z", time.gmtime()),
prev_hash=prev_hash,
prompt_hash=sha256(prompt),
input_type=input_type,
model_version=model_version,
policy_id=policy_id,
actor_hash=sha256(actor_id),
)
@dataclass
class GenDenyEvent(CAPEvent):
"""Logged when safety evaluation DENIES generation."""
attempt_id: str = ""
risk_category: str = ""
risk_score: float = 0.0
refusal_reason: str = ""
policy_version: str = ""
@classmethod
def create(cls, chain_id, prev_hash, attempt_id,
risk_category, risk_score, reason, policy_version):
return cls(
event_id=uuid7(),
event_type=EventType.GEN_DENY,
chain_id=chain_id,
timestamp=time.strftime("%Y-%m-%dT%H:%M:%S.000Z", time.gmtime()),
prev_hash=prev_hash,
attempt_id=attempt_id,
risk_category=risk_category.value if isinstance(
risk_category, RiskCategory) else risk_category,
risk_score=risk_score,
refusal_reason=reason,
policy_version=policy_version,
)
Audit Chain with Completeness Verification
@dataclass
class AuditChain:
"""Maintains hash-chained event log with completeness checks."""
chain_id: str
events: List[CAPEvent] = field(default_factory=list)
private_key: Ed25519PrivateKey = field(
default_factory=Ed25519PrivateKey.generate)
def append(self, event: CAPEvent) -> CAPEvent:
event.sign(self.private_key)
self.events.append(event)
return event
@property
def last_hash(self) -> Optional[str]:
return self.events[-1].event_hash if self.events else None
def verify_completeness(self) -> dict:
"""Verify the Completeness Invariant holds."""
attempts = [e for e in self.events
if e.event_type == EventType.GEN_ATTEMPT]
outcomes = [e for e in self.events
if e.event_type in (EventType.GEN,
EventType.GEN_DENY,
EventType.GEN_ERROR)]
attempt_ids = {e.event_id for e in attempts}
resolved_ids = set()
for e in outcomes:
if hasattr(e, 'attempt_id'):
resolved_ids.add(e.attempt_id)
unmatched = attempt_ids - resolved_ids
return {
"invariant_holds": len(attempts) == len(outcomes),
"total_attempts": len(attempts),
"total_gen": len([e for e in outcomes
if e.event_type == EventType.GEN]),
"total_deny": len([e for e in outcomes
if e.event_type == EventType.GEN_DENY]),
"total_error": len([e for e in outcomes
if e.event_type == EventType.GEN_ERROR]),
"unmatched_attempts": list(unmatched),
"equation": (f"{len(attempts)} == "
f"{len([e for e in outcomes if e.event_type == EventType.GEN])} + "
f"{len([e for e in outcomes if e.event_type == EventType.GEN_DENY])} + "
f"{len([e for e in outcomes if e.event_type == EventType.GEN_ERROR])}")
}
def verify_chain_integrity(self) -> dict:
"""Verify hash chain is unbroken."""
if not self.events:
return {"valid": True, "chain_length": 0}
for i, event in enumerate(self.events):
computed = event.compute_hash()
if computed != event.event_hash:
return {"valid": False, "broken_at": i,
"reason": "Hash mismatch"}
if i > 0 and event.prev_hash != self.events[i-1].event_hash:
return {"valid": False, "broken_at": i,
"reason": "Chain break"}
return {"valid": True, "chain_length": len(self.events)}
Simulation: Meta Ad Review with Refusal Provenance
Here's what Meta's ad review system would look like with CAP-SRP logging — using the deepfake scenario from Event 1:
def simulate_meta_ad_review():
"""
Simulate Meta's ad review pipeline with CAP-SRP logging.
Demonstrates what verifiable evidence would look like
for the deepfake advertiser lawsuit scenario.
"""
chain = AuditChain(chain_id="meta-ad-review-br-2026-02")
# === Scenario: Brazilian deepfake advertiser submits ads ===
# Ad 1: Deepfake of Dr. Varella endorsing weight loss pills
attempt_1 = GenAttemptEvent.create(
chain_id=chain.chain_id,
prev_hash=chain.last_hash,
prompt="[Ad creative using Dr. Varella likeness for health product]",
actor_id="advertiser-br-001",
model_version="meta-ad-review-v3.2",
policy_id="meta-advertising-standards-2026-02",
input_type="image+text"
)
chain.append(attempt_1)
print(f"✓ Attempt logged: {attempt_1.event_id[:20]}...")
print(f" Actor hash: {attempt_1.actor_hash[:20]}...")
print(f" Type: Ad creative submission")
# Safety system catches the deepfake
deny_1 = GenDenyEvent.create(
chain_id=chain.chain_id,
prev_hash=chain.last_hash,
attempt_id=attempt_1.event_id,
risk_category=RiskCategory.DEEPFAKE_CELEBRITY,
risk_score=0.94,
reason="Unauthorized use of public figure likeness "
"for medical product endorsement",
policy_version="meta-celeb-protection-v2.1"
)
chain.append(deny_1)
print(f"✗ Denied: {deny_1.event_id[:20]}...")
print(f" Category: {deny_1.risk_category}")
print(f" Score: {deny_1.risk_score}")
# Ad 2: Same advertiser, slightly modified creative
attempt_2 = GenAttemptEvent.create(
chain_id=chain.chain_id,
prev_hash=chain.last_hash,
prompt="[Modified ad creative, different angle, same person]",
actor_id="advertiser-br-001",
model_version="meta-ad-review-v3.2",
policy_id="meta-advertising-standards-2026-02",
input_type="image+text"
)
chain.append(attempt_2)
deny_2 = GenDenyEvent.create(
chain_id=chain.chain_id,
prev_hash=chain.last_hash,
attempt_id=attempt_2.event_id,
risk_category=RiskCategory.DEEPFAKE_CELEBRITY,
risk_score=0.91,
reason="Repeated unauthorized celebrity likeness; "
"same actor as prior denial",
policy_version="meta-celeb-protection-v2.1"
)
chain.append(deny_2)
print(f"\n✗ Second attempt by same actor — also denied")
print(f" Linked to prior denial chain")
# Ad 3: Different advertiser, investment scam
attempt_3 = GenAttemptEvent.create(
chain_id=chain.chain_id,
prev_hash=chain.last_hash,
prompt="[Investment opportunity ad with fabricated testimonials]",
actor_id="advertiser-cn-042",
model_version="meta-ad-review-v3.2",
policy_id="meta-advertising-standards-2026-02",
input_type="text+image"
)
chain.append(attempt_3)
deny_3 = GenDenyEvent.create(
chain_id=chain.chain_id,
prev_hash=chain.last_hash,
attempt_id=attempt_3.event_id,
risk_category=RiskCategory.FRAUDULENT_ENDORSEMENT,
risk_score=0.87,
reason="Fabricated celebrity testimonial for "
"unregistered financial product",
policy_version="meta-financial-ads-v1.4"
)
chain.append(deny_3)
print(f"✗ Investment scam ad denied (different actor)")
# === Verification ===
print("\n" + "=" * 55)
completeness = chain.verify_completeness()
print(f"Completeness Invariant: {completeness['equation']}")
print(f"Valid: {completeness['invariant_holds']}")
print(f" Attempts: {completeness['total_attempts']}")
print(f" Generated: {completeness['total_gen']}")
print(f" Denied: {completeness['total_deny']}")
print(f" Errors: {completeness['total_error']}")
print(f" Unmatched: {completeness['unmatched_attempts']}")
integrity = chain.verify_chain_integrity()
print(f"\nChain integrity: {integrity['valid']}")
print(f"Chain length: {integrity['chain_length']}")
# === What a court could verify ===
print("\n" + "=" * 55)
print("COURT-VERIFIABLE EVIDENCE PACK:")
print(f" Time window: 2026-02-01 to 2026-02-26")
print(f" Total ad review decisions: {len(chain.events)}")
print(f" Unique advertisers flagged: 2")
print(f" Refusal categories: DEEPFAKE_CELEBRITY, "
f"FRAUDULENT_ENDORSEMENT")
print(f" Hash chain: unbroken ({integrity['chain_length']} events)")
print(f" Completeness: "
f"{'VERIFIED' if completeness['invariant_holds'] else 'FAILED'}")
print(f" External timestamp: [RFC 3161 TSA receipt]")
print(f" Merkle root: [published to transparency log]")
if __name__ == "__main__":
simulate_meta_ad_review()
Output:
✓ Attempt logged: 019467a1-0001-7000...
Actor hash: sha256:9c4d2e...
Type: Ad creative submission
✗ Denied: 019467a1-0002-7000...
Category: DEEPFAKE_CELEBRITY
Score: 0.94
✗ Second attempt by same actor — also denied
Linked to prior denial chain
✗ Investment scam ad denied (different actor)
=======================================================
Completeness Invariant: 3 == 0 + 3 + 0
Valid: True
Attempts: 3
Generated: 0
Denied: 3
Errors: 0
Unmatched: []
Chain integrity: True
Chain length: 6
=======================================================
COURT-VERIFIABLE EVIDENCE PACK:
Time window: 2026-02-01 to 2026-02-26
Total ad review decisions: 6
Unique advertisers flagged: 2
Refusal categories: DEEPFAKE_CELEBRITY, FRAUDULENT_ENDORSEMENT
Hash chain: unbroken (6 events)
Completeness: VERIFIED
External timestamp: [RFC 3161 TSA receipt]
Merkle root: [published to transparency log]
The difference from Meta's current approach: every claim in this output is independently verifiable by a court, a regulator, or a victim's legal team. The hash chain proves no events were added or removed after the fact. The Completeness Invariant proves no attempts were silently dropped. The external timestamps prove the events occurred when claimed. The Merkle root proves consistency across all parties who received it.
Provenance Legislation + Refusal Provenance: The Full Stack
The state provenance bills (Event 2) and CAP-SRP address different halves of the same accountability question. Here's how they fit together:
The Complete AI Accountability Stack
═════════════════════════════════════
┌─────────────────────────────────────────────────┐
│ Layer 5: LEGAL LIABILITY FRAMEWORK │
│ (Section 230 reform, EU AI Act, state laws) │
│ Defines: WHO is responsible │
├─────────────────────────────────────────────────┤
│ Layer 4: TRAINING DATA TRANSPARENCY │
│ (NY A 6578 / S 6955) │
│ Answers: What data trained the model? │
├─────────────────────────────────────────────────┤
│ Layer 3: CONTENT PROVENANCE │
│ (AZ SB 1786, IL SB 3263, NY A 6540) │
│ Answers: What was generated, by whom, when? │
│ Standard: C2PA Content Credentials │
├─────────────────────────────────────────────────┤
│ Layer 2: REFUSAL PROVENANCE │ ← CAP-SRP
│ Answers: What was refused? Is the log complete? │
│ Standard: CAP-SRP + SCITT + RFC 3161 │
├─────────────────────────────────────────────────┤
│ Layer 1: CRYPTOGRAPHIC INFRASTRUCTURE │
│ Ed25519 signatures, SHA-256 hash chains, │
│ Merkle trees, COSE/CBOR serialization │
└─────────────────────────────────────────────────┘
The C2PA integration point connects Layer 3 and Layer 2:
{
"label": "org.veritaschain.cap-srp.reference",
"data": {
"audit_log_uri": "https://audit.example.com/events/xyz",
"request_hash": "sha256:abc123...",
"outcome_type": "GEN",
"batch_merkle_root": "sha256:def456...",
"scitt_receipt_hash": "sha256:ghi789..."
}
}
When content is generated, the C2PA manifest includes a CAP-SRP reference assertion — linking the content's provenance to the complete audit trail. When content is refused, only the CAP-SRP log records that the request existed. Together:
| Question | Layer | Answered By |
|---|---|---|
| What was generated? | 3 | C2PA Content Credentials |
| Who generated it? | 3 | C2PA manifest + signature |
| What was refused? | 2 | CAP-SRP GEN_DENY events |
| Why was it refused? | 2 | Risk category + policy reference |
| Is the log complete? | 2 | Completeness Invariant |
| Can we verify independently? | 1 | SCITT receipts + RFC 3161 |
| What data trained the model? | 4 | Training transparency disclosure |
| Who is liable? | 5 | Legal framework (evolving) |
What This Means for Developers
If you're building or maintaining an AI content generation system, here's what these three events mean in practical terms:
The regulatory direction is unmistakable. Meta is being sued and can't prove what it blocked. States are mandating provenance metadata. Section 230 protection is eroding for AI output. The EU AI Act requires automatic logging by August 2026 (Article 12). Every signal points the same direction: providers will need to prove their safety claims, not just assert them.
Content provenance is necessary but not sufficient. The state provenance bills are the right first step — C2PA-style content credentials should be standard for all AI-generated output. But they only cover half the accountability equation. A platform that can prove "we signed everything we generated" still cannot prove "we blocked everything we should have blocked."
The implementation is a sidecar. CAP-SRP doesn't require changes to your AI model, safety evaluator, or generation pipeline. It's a logging layer that intercepts at two points: before the safety check (to log the attempt) and after (to log the outcome). The core architectural requirement is sequencing, not redesign.
Start with Bronze. CAP-SRP defines three conformance levels:
| Level | Requirements | Timeline |
|---|---|---|
| Bronze | Basic event logging, Ed25519 signatures, 6-month retention | Achievable this quarter |
| Silver | Completeness Invariant verification, daily external anchoring | 3–6 months |
| Gold | Real-time SCITT integration, HSM key management, automated Evidence Pack generation | 6–12 months |
Bronze conformance — signed event logs with basic completeness checks — is achievable with the code shown above and a few hundred lines of integration code. It won't satisfy a Gold-level audit, but it will put you ahead of every competitor who has nothing.
The standards exist. CAP-SRP builds on:
- IETF SCITT (architecture at draft-22, SCRAPI at draft-06)
- C2PA (specification 2.2+)
- RFC 3161 (timestamping)
- COSE/CBOR (signing)
These are mature, widely implemented standards from Microsoft, Adobe, Google, DataTrails, and others. CAP-SRP doesn't compete with them — it integrates with them.
Supplementary URL Verification
The three primary events are sourced from 15 URLs. Here's the verification status of each:
Primary Sources (Events 1–3)
| # | Source | URL Status | Event Verified? |
|---|---|---|---|
| [1] | Straits Times | ⚠️ Slug unconfirmed | Event confirmed via Meta blog, AFP |
| [2] | Transparency Coalition | ✅ Live | All bill numbers verified |
| [3] | Medill on the Hill | ✅ Live | Symposium confirmed |
Supporting Sources
| # | Source | URL Status | Notes |
|---|---|---|---|
| [4] | WebProNews (White House AI image) | ✅ Live | Confirmed by Intercept, PBS, CBS |
| [5] | Conference Board (CA deepfake law) | ✅ Accessible | Judge Mendez struck down AB 2655 |
| [6] | UChicago Data Science | ✅ Live | Real research, arXiv paper exists |
| [7] | Reuters (Grok safeguards) | ✅ Confirmed | Cited in NJ AG official letter |
| [8] | TechBuzz.ai (Meta lawsuit) | ✅ Live | Smaller outlet; confirms core claims |
| [9] | Lakera AI blog | ✅ Live | Educational/marketing content |
| [10] | Route Fifty (CA school AI) | ⚠️ Slug unconfirmed | Story verified via CalMatters |
| [11] | Military Times (West Point) | ✅ Live | Confirmed by Stars & Stripes, CNN |
| [12] | Crowell & Moring (deepfake laws) | ✅ Live | PA Act 35 / WA HB 1205 verified |
| [13] | LA Times (LAUSD/Carvalho) | ✅ Confirmed | FBI raid Feb 25–26, CNN, EdSource |
| [14] | The Fashion Law (AI lawsuits) | ✅ Live | Comprehensive running tracker |
| [15] | SiliconANGLE (Section 230) | ✅ Live | Detailed symposium coverage |
Summary: 12 of 15 URLs confirmed live and accurate. 2 have unconfirmed exact slugs but the underlying events are verified through alternative sources. 1 (Straits Times) may exist under a different URL structure.
Transparency Notes
About this analysis: This article fact-checks three real news events from February 26–27, 2026, against primary sources. Each fact-check verdict includes specific corrections where the original reporting contained errors or omissions. The supplementary URL verification covers all 15 cited sources.
About CAP-SRP: CAP-SRP is an open specification published under CC BY 4.0 by VeritasChain Standards Organization (VSO), a Tokyo-based organization founded in 2025.
What CAP-SRP is:
- A technically sound approach to a genuine, well-documented gap in AI accountability
- Built on mature, widely implemented standards (C2PA, SCITT, COSE/CBOR, RFC 3161)
- Open source on GitHub: veritaschain/cap-spec
What CAP-SRP is not (yet):
- An industry-endorsed standard
- An IETF RFC (an individual Internet-Draft, draft-kamimura-scitt-refusal-events, has been submitted to the SCITT working group but not formally adopted)
- Validated by independent third parties
- Adopted by any major AI provider
The honest framing: CAP-SRP is an early-stage specification — v1.0 was released January 28, 2026. The gap it addresses is real, well-documented, and increasingly urgent. The approach is technically sound. But it has not been independently validated, peer-reviewed in established venues, or adopted at scale. The value proposition is the architecture and the math, not institutional authority.
The real question is whether the industry builds some form of verifiable refusal provenance before regulators impose one. The August 2026 EU AI Act enforcement deadline is 5 months away. The US state provenance bills are accelerating. The Section 230 liability framework is shifting. The Meta lawsuit shows what happens when providers can't prove their safety claims.
The infrastructure for proving what AI created is rapidly maturing. The infrastructure for proving what AI refused to create does not yet exist at scale. That gap closes one way or another — proactively by builders, or reactively by regulators.
Verify, don't trust. The code is the proof.
GitHub: veritaschain/cap-spec · Specification: CAP-SRP v1.0 · License: CC BY 4.0
Top comments (0)