Engineering guide · updated 24 July 2026
Article 50 AI disclosure regression testing in CI
Turn the AI disclosure your governance team selected into a repeatable release check. Test the delivered page, retain time-bound evidence, and keep legal scope outside the test runner.
Open-source v0.4.0 technical preview · local-first · no telemetry · configured assertions only
Start with the boundary
CI can catch a regression. It cannot make the legal decision.
Article 50 separates several provider and deployer obligations and includes fact-specific scope questions and exceptions. The relevant transparency obligations apply from 2 August 2026, but a test runner cannot responsibly decide whether a system is in scope, whether an exception applies, or whether a disclosure is legally sufficient.
The useful handoff begins after accountable people have selected a control: a notice, selector, expected wording, delivery surface, and—where the organisation has chosen it—a machine-readable provenance profile. Those declared mechanics can be tested like any other release invariant.
art50-ci tests observable technical conditions supplied by the team. It does not determine scope, interpret exceptions, certify compliance, or provide legal advice.
The deployment gap
An approved disclosure can still fail after release.
Copy or markup drifts
A component refactor removes the notice, changes the expected wording, or breaks the stable selector.
Responsive layout hides it
A mobile breakpoint pushes the disclosure below the initial viewport or a cookie banner covers sampled points.
Delivery strips metadata
A CDN or media transformation removes the configured C2PA provenance from the bytes people actually receive.
These are delivery regressions. That makes them suitable for repeatable checks against preview and production—not proof of compliance, but useful evidence that an agreed technical control survived.
Run a source-to-delivery C2PA regression testDeclared expectations
What art50-ci can observe
| Declared expectation | Observable check | Evidence |
|---|---|---|
| Disclosure is present | A stable selector exists and its text matches the wording supplied by the team. | URL, timestamp, match result, and precise failure code |
| Disclosure appears initially | The element is observed in the initial page state before any configured interaction is performed. | Initial-state and viewport result |
| Disclosure meets the configured display checks | Visibility, initial-viewport intersection, sampled obstruction, and a basic accessible name are checked. | Structured result and screenshot when enabled |
| Configured provenance survives delivery | When both assets and the chain assertion are configured, the source active manifest label is sought in the delivered active manifest's ingredient ancestry. | Inspected-asset hashes and privacy-minimised provenance summary |
PASS has a narrow meaning: the configured condition was observed against that target, viewport, and time.
C2PA is optional—and not a truth verdict.
Article 50 does not require C2PA by name. art50-ci supports it as one configurable metadata implementation and does not provide complete Article 50(2) marking or detection coverage. Content Credentials can provide cryptographically bound, signed provenance and tamper-evidence; they do not establish that an assertion is factually true, that content is lawful, or that Article 50 is satisfied.
No account · no upload · five minutes
Build your first production disclosure check.
Enter one public product URL and the disclosure your team selected. The command is assembled entirely in this browser and runs locally on your machine.
- Nothing is submitted or stored
- No customer media or credentials
- Inspectable JSON, HTML, and screenshot evidence
Founding offer · 30-day monitored launch
€500 monitored launch.
The open-source software remains free to self-serve. €500 buys delivery and accountability—not access to the code.
- Working release gate for one product and up to five declared checks
- Configuration and one GitHub Actions workflow integrated
- Reproducible baseline run and evidence delivered: a confirmed pass or product failure
- Up to three distinct failed-run causes triaged during the 30-day window
- Agreed configuration, workflow, evidence index, and runbook handoff
Each browser disclosure assertion, optional first-interaction control, or C2PA provenance item counts as one check.
Public 60-second fit check. No product URLs, media, repository access, private details, or payment. Preliminary fit or no-fit comes first; private intake requires explicit opt-in. Daily or weekly monitoring is asynchronous, with no on-call or response-time SLA. Engineering delivery only: no legal advice or certification, C2PA creation or embedding, trust determination, or product fixes. Evidence is handed off; hosted custody is not included.
Promote the check
Put the same expectation in GitHub Actions.
The browser builder produces a one-off local command. For a source-controlled release gate, add a configuration file and a workflow. This complete example runs against the public art50-ci site; replace the target, selector, and text with the disclosure your team selected.
.art50-ci.yml
version: 1
project:
name: first-art50-ci-check
surfaces:
- id: public-ai-disclosure
kind: website
target: https://art50-ci.rubiss89.chatgpt.site
disclosures:
- id: disclosure
selector: '[data-product-boundary]'
expectedText: No legal compliance verdicts..github/workflows/art50-ci.yml
name: AI transparency regression
on:
pull_request:
workflow_dispatch:
permissions:
contents: read
jobs:
disclosure-check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: Rubiss/art50-ci@v0.4.0
with:
config: .art50-ci.ymlThe v0.4.0 composite Action supports GitHub-hosted Linux runners. It installs its runtime outside the caller workspace. For a completed audit, it uploads the validated report directory before propagating 0 for a pass or 1 for failed assertions. Configuration or execution failures use 2; an error before report creation may produce no artifact.
Run it on pull requests to catch changes before merge, then schedule the same declared check against production. Each completed report remains a time-bound observation—not continuous monitoring.
npm does not propagate a dependency package's overrides. Projects installing the CLI can therefore still see four high-severity audit findings in the @contentauth/c2pa-node install-time unzipper@0.10.14 dependency chain. The tagged Action and repository lockfile use unzipper@0.12.5; removing the npm consumer warnings fully requires an upstream C2PA dependency-range update.
Operational ownership
Make the governance-to-engineering handoff explicit.
A reliable test starts with a reviewed expectation, not a heuristic that tries to infer policy from a page. Record who selected the control, what should be present, where it should appear, and which changes require renewed human review.
Decide scope, actor role, wording, target surfaces, locales, and the technical control to implement.
Add stable selectors, identify the intended viewport and readiness condition, and preserve the control through delivery.
Run the declared assertions against preview and production, then retain time-bound evidence.
Interpret failures, review exceptions and legal sufficiency, and decide remediation.
Add stable attributes such as data-ai-disclosure rather than targeting fragile presentation classes. Treat new content classes, exceptions, label wording, and delivery-pipeline changes as manual review gates.
Release evidence
Retain enough context to reproduce the observation.
An art50-ci evidence bundle can include:
- Matching structured JSON and rendered HTML reports
- Screenshots when enabled
- Serialized-page-DOM, screenshot, and inspected-asset SHA-256 hashes
- Timestamp, tested URL, viewport, configuration hash, and optional GitHub commit SHA
- Precise failure codes and provenance summaries
Screenshots are full-page and enabled by default, so they can contain customer or account information. Screenshot selector masks do not redact the JSON or HTML report, which can retain configured or observed text, selectors, accessible names, and URL host or path. Disable screenshots on sensitive pages, minimise the configuration, and keep uploaded artifacts in access-controlled storage. art50-ci has no telemetry and does not upload inspected media to its maintainers, but configured targets are still accessed and GitHub Actions uploads the evidence you choose to retain.
Choose the path
Self-serve for free. Choose a monitored launch for delivery and accountability.
Self-serve
Free local check
- Best for one public URL and stable selector
- Five-minute command assembled in your browser
- Your team owns configuration and workflow
- Open-source v0.4.0 technical preview
Founding offer · 30-day monitored launch
€500 one time
The open-source software remains free to self-serve. €500 buys delivery and accountability—not access to the code.
- Working release gate for one product and up to five declared checks
- Configuration and one GitHub Actions workflow integrated
- Reproducible baseline run and evidence delivered: a confirmed pass or product failure
- Up to three distinct failed-run causes triaged during the 30-day window
- Agreed configuration, workflow, evidence index, and runbook handoff
Each browser disclosure assertion, optional first-interaction control, or C2PA provenance item counts as one check.
Check monitored launch fit Read the exact delivery scopePublic 60-second fit check. No product URLs, media, repository access, private details, or payment. Preliminary fit or no-fit comes first; private intake requires explicit opt-in. Daily or weekly monitoring is asynchronous, with no on-call or response-time SLA. Engineering delivery only: no legal advice or certification, C2PA creation or embedding, trust determination, or product fixes. Evidence is handed off; hosted custody is not included.
Result boundaries
Frequently asked questions
Can art50-ci determine whether Article 50 applies?
No. Scope, roles, exceptions, classifications, and legal sufficiency remain decisions for accountable people.
Does a passing run prove compliance?
No. PASS means only that the configured technical condition was observed against the tested target, viewport, and time.
Does it judge disclosure wording?
No. It matches wording supplied by the team. It cannot decide whether that wording is clear, distinguishable, accessible, or legally sufficient in context.
Does it perform the configured interaction?
No. It observes the initial state, then checks that the configured control exists, is visible, and is enabled. It does not activate the control.
Is this a full accessibility audit?
No. The accessible-name assertion is deliberately basic and does not establish WCAG conformance or replace assistive-technology testing.
Does it verify C2PA authenticity or signer trust?
No. It inspects configured manifest properties and delivery ancestry. Content Credentials do not establish that an assertion is factually true, and this preview does not make a signer-trust determination.
Can it test private staging?
The CLI supports an exact scheme, host, and port only when the configuration requests it and the operator separately grants it at runtime, with no wildcards. The runner must already have network reachability, and the page must be accessible to a fresh browser context; art50-ci does not establish tunnels or perform login setup. The browser builder on this page accepts public HTTP or HTTPS URLs.
Which CI environment is supported?
The v0.4.0 composite Action supports GitHub-hosted Linux runners. The local CLI can also be run directly where its Node.js and Chromium requirements are met.
Primary sources
Use the official materials for policy decisions.
The Commission published its final Article 50 guidelines on 20 July 2026. They and the Regulation—not this guide or a test result—are the starting points for determining obligations.
Make the control repeatable
Start with one disclosure on one real URL.
Build the local command now and keep self-serving for free. If you want us accountable for delivery and the first 30 days, the founding monitored launch is €500.