{"slug": "labeling-ai-content-for-russia-s-march-2027-rules-an-engineering-checklist", "title": "Labeling AI content for Russia's March 2027 rules: an engineering checklist", "summary": "A developer published an engineering checklist for complying with Russia's AI content labeling rules, which take effect 1 March 2027, covering provenance manifests, JSON Schema validation, ExifTool metadata embedding and ffmpeg remuxing. The approach pairs each asset with a single manifest sharing an ID, then derives file metadata, visible labels and HTTP headers from that one source so the provenance record cannot drift or be silently stripped. The author estimates 90–120 minutes for the first asset and about ten minutes for each subsequent one once the schema, metadata commands and CI verification script exist.", "body_md": "Russian rules on labeling AI-generated content take effect on 1 March 2027. The legal analysis belongs to someone else; what landed on my desk is the engineering side — making sure every asset that leaves the pipeline carries a provenance record both a person and a machine can read, and that it cannot quietly lose that record later. Below is the setup I would hand to another developer.\n\nBudget 90–120 minutes for the first asset. Once the manifest format, the metadata commands and the CI script exist, each additional asset costs roughly ten minutes.\n\nRule number one: every artifact gets one manifest and one asset file sharing the same ID. That single convention is what makes everything else scriptable — checksums, metadata writing and the CI loop all key off the same name.\n\n```\nmkdir -p ai-labeling/{schema,manifests,assets,scripts}\ncd ai-labeling\ngit init\nai-labeling/\n├── schema/label.schema.json\n├── manifests/img-2027-0001.json\n├── assets/img-2027-0001.jpg\n└── scripts/verify_labels.sh\n```\n\nTools to have ready, with the version check I run first:\n\n`jsonschema` package (`pip install jsonschema`); confirm with `python3 --version`.` ajv-cli` runs through `npx`, so there is nothing to install globally: check `node -v` and `npx --version`.` exiftool -ver`.` ffmpeg -version | head -n 1`.`$PSVersionTable.PSVersion`.\nThe manifest is a plain-text provenance record: what produced the asset, when, and whether a human reviewed it. It exists before any output surface, so the file metadata, the page label and the API header are all derived from one source and cannot drift apart. Writing it first also forces you to capture the model identifier while you still have it — copy the exact string from the API response body, never type a model name from memory.\n\n`manifests/img-2027-0001.json`:\n\n```\n{\n  \"asset_id\": \"img-2027-0001\",\n  \"asset_sha256\": \"<output-of-sha256sum>\",\n  \"created_at\": \"2027-02-14T10:22:00Z\",\n  \"origin\": \"ai-generated\",\n  \"model_provider\": \"<provider-name-from-your-contract>\",\n  \"model_id\": \"<exact-model-id-returned-by-the-api>\",\n  \"ai_generated_share\": 1.0,\n  \"human_reviewed\": true,\n  \"reviewer\": \"editor@example.com\",\n  \"reviewed_at\": \"2027-02-14T11:05:00Z\",\n  \"disclosure\": { \"visible_label\": \"AI-generated image\", \"machine_readable\": true }\n}\n```\n\nFor AI-written text that an editor reworked, keep the same schema and set `origin` to `ai-assisted`.\n\nDescribe the fields in `schema/label.schema.json` and make these required: `asset_id`, `asset_sha256`, `created_at`, `origin`, `model_id`, `ai_generated_share`, `human_reviewed`, `disclosure`. Then hash the file and validate:\n\n``` python\nsha256sum assets/img-2027-0001.jpg > checksums.txt\npython3 -c \"import json,jsonschema;jsonschema.validate(json.load(open('manifests/img-2027-0001.json')),json.load(open('schema/label.schema.json')));print('manifest valid')\"\n```\n\n**Confirm the schema actually enforces something:** the terminal should print `manifest valid`. Then copy the manifest, remove `model_id`, validate the copy, and check that you get a `ValidationError` naming that field. A schema that never fails is decoration.\n\nThree different readers need three different surfaces. Metadata inside the file survives download and re-upload. The visible label is what a human sees. An HTTP header is what an automated client sees. A caption alone vanishes the moment someone embeds the image elsewhere, and metadata alone is invisible to a reader — ship both.\n\nImage metadata with ExifTool (`-overwrite_original` keeps `.jpg_original` backups out of your build output):\n\n```\nexiftool -overwrite_original \\\n  -XMP-dc:Description=\"AI-generated image. Model: <model-id>. Provenance: /provenance/img-2027-0001.json\" \\\n  -XMP-xmpMM:DocumentID=\"img-2027-0001\" \\\n  assets/img-2027-0001.jpg\n```\n\nFor video, `-codec copy` remuxes without re-encoding, so quality is untouched and the job finishes in seconds:\n\n```\nffmpeg -i assets/clip-2027-0002.mp4 -codec copy \\\n  -metadata comment=\"AI-generated video; provenance clip-2027-0002\" \\\n  assets/clip-2027-0002.labeled.mp4\n```\n\nPage markup — one tag for machines, one sentence for people:\n\n```\n<meta name=\"ai-generated\" content=\"true\">\n<p class=\"ai-disclosure\">AI-generated image. <a href=\"https://dev.to/provenance/img-2027-0001.json\">Provenance record</a></p>\n```\n\nAnd on every API endpoint that returns generated text, image or audio:\n\n```\nX-AI-Generated: true\nX-AI-Provenance: /provenance/img-2027-0001.json\n```\n\nIf your provider supports embedded, signed provenance manifests, sign the file with `c2patool` instead of plain XMP. Flag names and signing-key setup change between releases, so read the current docs and pin the version you used.\n\n**Check both surfaces:** `exiftool -s3 -XMP-dc:Description assets/img-2027-0001.jpg` should print the description line, and `curl -sI https://<your-domain>/api/render | grep -i x-ai-generated` should return `x-ai-generated: true`.\n\nLabels disappear quietly. Design tools, image optimizers and CDN pipelines strip XMP blocks without complaint, and nobody notices until someone else does. A failing build is the only reminder that survives a team change.\n\n`scripts/verify_labels.sh`:\n\n``` bash\n#!/usr/bin/env bash\nset -euo pipefail\nnpx ajv-cli validate -s schema/label.schema.json -d \"manifests/*.json\" --errors=text\nsha256sum -c checksums.txt\nfor f in assets/*.jpg; do\n  exiftool -s3 -XMP-dc:Description \"$f\" | grep -q \"AI-generated\" \\\n    || { echo \"MISSING LABEL: $f\"; exit 1; }\ndone\necho \"all labels verified\"\n```\n\nWire it into CI as a single step running `bash scripts/verify_labels.sh`, and make that step required for merges.\n\n**Check it end to end:** three lines should appear in order — `manifests/img-2027-0001.json valid`, `assets/img-2027-0001.jpg: OK`, `all labels verified`. Then copy an asset, strip it with `exiftool -all= assets/test-unlabeled.jpg`, re-run the script and confirm you see `MISSING LABEL: assets/test-unlabeled.jpg` followed by `echo $?` printing `1`.\n\nScope is a legal question, not a build question. Which of your outputs fall under the rules, which exemptions apply, and the exact wording of the disclosure all have to be confirmed against the current regulation text with your legal team before you ship anything. Everything above covers only the mechanics of producing and enforcing the label.\n\n`model_id` from the API response at generation time, not from memory.\nThis article was originally published on AI Release — [https://ai-release.org](https://ai-release.org). Shorter, recurring notes on tooling and compliance work like this show up in the channel at [https://t.me/ai_release1](https://t.me/ai_release1).", "url": "https://wpnews.pro/news/labeling-ai-content-for-russia-s-march-2027-rules-an-engineering-checklist", "canonical_source": "https://dev.to/qunirice_verase_1ab0caeba/labeling-ai-content-for-russias-march-2027-rules-an-engineering-checklist-3pln", "published_at": "2026-11-11 10:12:40+00:00", "updated_at": "2026-11-11 10:24:16.369342+00:00", "lang": "en", "topics": ["ai-policy", "ai-safety", "ai-ethics", "developer-tools"], "entities": ["Russia", "ExifTool", "ffmpeg", "jsonschema", "ajv-cli"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/labeling-ai-content-for-russia-s-march-2027-rules-an-engineering-checklist", "markdown": "https://wpnews.pro/news/labeling-ai-content-for-russia-s-march-2027-rules-an-engineering-checklist.md", "text": "https://wpnews.pro/news/labeling-ai-content-for-russia-s-march-2027-rules-an-engineering-checklist.txt", "jsonld": "https://wpnews.pro/news/labeling-ai-content-for-russia-s-march-2027-rules-an-engineering-checklist.jsonld"}}