An evidence-first technical checker for observable EU AI Act Article 50 properties, plus a separate set of disclosure and provenance helpers.
I built this after realizing that configuration is not evidence. A configured notice does not prove that a person saw it, and a manifest format does not prove that deployed content carried a mark. The checker therefore starts from what a web target actually serves and links every finding to a receipt.
This is engineering software, not legal advice or a compliance determination.
- Crawls server-delivered, same-origin HTML from a target you name.
- Discovers candidate systems from observable page semantics and forms.
- Records SHA-256 receipts for accepted pages and active-probe responses.
- Tests first-exposure notices, delivery semantics, and supported marking carriers without importing the repository's marking helpers.
- Separates observed facts, target representations, and unresolved questions.
- Routes Article 50 duties and transition timing per system and article.
- Emits JSON and Markdown reports whose findings cite their evidence IDs.
- Rejects foreign redirects, oversized responses, invalid dates, and unsafe target credentials.
The package also exposes optional Ed25519 provenance, disclosure middleware, governance records, and a best-effort text watermark. Those helpers are kept outside the checker so they cannot grade their own output.
Requirements: Node.js 20 or newer. There are no runtime dependencies, API keys, or accounts.
npm ci
npm run demo:reportThe demo builds the project, starts a loopback reference target, runs the real checker with active probing, and writes:
art50-report/
report.json
report.md
To inspect a web deployment you are authorized to test:
npm run build
node dist/src/cli.js check \
--target https://your-target.example \
--out ./art50-report \
--as-of 2026-08-12Add --active only when the target has explicitly marked same-origin endpoints
as probeable. The default mode crawls without invoking those endpoints.
Authorized web target
|
v
+------------------+ accepted bytes +------------------+
| same-origin crawl|------------------------>| evidence receipts|
+--------+---------+ +---------+--------+
| |
v |
+------------------+ independent parse |
| discovery + probe|---------------------------+ |
+--------+---------+ | |
| v v
| +------+-------+--+
+------------------------------>| rules + routing |
+------+----------+
|
v
report.json + report.md
Separate remediation path:
content -> provenance + disclosure + governance -> sidecar / label / record
(never feeds the checker)
The checker uses the target as untrusted input. Redirects are followed manually so the next origin can be approved before any request is sent. Active probing is limited to explicitly opted-in endpoints on that same origin.
Verdicts are scoped to individual checks:
pass: the named observable check passed for the collected evidence.fail: the named observable check failed.manual_review_required: the answer depends on facts a crawler cannot prove.not_tested: the adapter does not observe this property.not_applicable: the routed duty does not apply under the represented facts.error: the check could not complete safely.
A report never turns a missing system into a clean bill of health. It names the authenticated, client-rendered, native, voice, or otherwise unreachable surfaces that still need human review.
The legal rule set and duty-timing logic are versioned in the report. Read docs/article-50.md for the source mapping and docs/checker.md for the evidence and verdict contract.
The package can also mark content and verify its signed sidecar:
import { AiActKit } from "ai-act-kit";
const kit = new AiActKit();
const marked = kit.mark({
content: "Example text",
contentType: "text",
purpose: "public-interest-text",
generator: { name: "example-system", version: "1" },
});
const verdict = kit.verify(marked.boundContent, marked.signedManifest);
console.log(verdict.signatureValid, verdict.contentMatches);Without configured key paths, the helper uses an ephemeral signing identity. Generate a persistent Ed25519 key pair with:
npm run build
node dist/src/cli.js keygen --out ./keys
cp config.example.json config.json
chmod 600 config.jsonReal configuration, private keys, runtime data, and generated reports are ignored by Git.
- The checker sees server-delivered anonymous web content. It does not execute client-side JavaScript or inspect authenticated, mobile, native, or voice experiences.
- It does not parse image, audio, or video containers for embedded credentials.
- Active probes support one narrow form request shape. Other APIs need adapters.
- Accessibility checks cover delivered markup semantics, not computed styles, keyboard behavior, assistive technology, contrast, zoom, or localization.
- Target declarations are claims, not documentary facts. Role, territorial scope, market dates, exceptions, and editorial responsibility remain review questions.
- The provenance helper is C2PA-aligned JSON with an Ed25519 signature, not full JUMBF/COSE embedding in a media file.
- Text sidecars and reference tokens can be stripped. The optional zero-width watermark is removable and is off by default.
- The helper audit log records calls but is not tamper-evident. Do not treat it as an independent conformance record.
- The rule set is pinned, not timeless. Re-check the governing text and update the versioned rules when the law or official guidance changes.
More detail on these boundaries is in ARCHITECTURE.md.
npm run build
npm startThe local dashboard and JSON API listen on http://localhost:8099. Docker users
can run docker compose up --build; runtime records persist in ./data.
Worked integrations live in examples/: a FastAPI service and an n8n
workflow both call POST /api/mark.
npm run build
npm testThe suite exercises discovery, redirects, hostile inputs, disclosure placement, provenance signatures, content binding, governance reports, the HTTP service, and watermark removal. Its network tests bind loopback only.
src/checker/ crawl, discovery, probes, detectors, rules, and reports
src/c2pa/ provenance manifests, signing, embedding, and verification
src/disclosure/ visible labels and middleware
src/governance/ audit records, inventory, and report scaffolds
src/server/ local dashboard and JSON API
test/ unit, integration, hostile, and reference-target tests
docs/ legal mapping and checker contract
examples/ FastAPI and n8n integrations
MIT. See LICENSE.