{
  "schemaVersion": 1,
  "release": "LAB-2026-08-12.2",
  "reviewedAt": "2026-08-12",
  "datasetType": "implementation-capability-ledger",
  "evidencePolicy": {
    "source-linked": "An implementation path exists and is named in the record.",
    "unit-covered": "An automated test covers the named logic; it may use synthetic input.",
    "fixture-pending": "No redistributable external-application fixture result is claimed for this record yet.",
    "fixture-confirmed": "An in-repository synthetic container fixture passed actual cleanup with published before, after and media-payload SHA-256 values. This is format-path evidence, not exporter compatibility.",
    "external-fixture-confirmed": "A redistributable external-application export passed actual cleanup with source, license and published before, after and media-payload SHA-256 values."
  },
  "capabilities": [
    {
      "id": "jpeg",
      "formats": [
        "JPEG",
        "JPG"
      ],
      "media": "image",
      "cleanupStrategy": "lossless",
      "selective": true,
      "sections": [
        "c2pa",
        "exif",
        "xmp",
        "iptc",
        "comments"
      ],
      "condition": "container-parser",
      "implementation": [
        "app/lib/metadata-cleaner.ts#cleanJpeg"
      ],
      "evidence": [
        "source-linked",
        "fixture-confirmed",
        "external-fixture-confirmed"
      ]
    },
    {
      "id": "png",
      "formats": [
        "PNG"
      ],
      "media": "image",
      "cleanupStrategy": "lossless",
      "selective": true,
      "sections": [
        "c2pa",
        "exif",
        "xmp",
        "iptc",
        "comments",
        "timestamps"
      ],
      "condition": "container-parser",
      "implementation": [
        "app/lib/metadata-cleaner.ts#cleanPng"
      ],
      "evidence": [
        "source-linked",
        "fixture-confirmed",
        "external-fixture-confirmed"
      ]
    },
    {
      "id": "webp",
      "formats": [
        "WebP"
      ],
      "media": "image",
      "cleanupStrategy": "lossless",
      "selective": true,
      "sections": [
        "c2pa",
        "exif",
        "xmp"
      ],
      "condition": "container-parser",
      "implementation": [
        "app/lib/metadata-cleaner.ts#cleanRiff:webp"
      ],
      "evidence": [
        "source-linked",
        "fixture-pending"
      ]
    },
    {
      "id": "gif",
      "formats": [
        "GIF"
      ],
      "media": "image",
      "cleanupStrategy": "lossless",
      "selective": true,
      "sections": [
        "c2pa",
        "comments"
      ],
      "condition": "container-parser",
      "implementation": [
        "app/lib/metadata-cleaner.ts#cleanGif"
      ],
      "evidence": [
        "source-linked",
        "fixture-pending"
      ]
    },
    {
      "id": "wav",
      "formats": [
        "WAV",
        "WAVE"
      ],
      "media": "audio",
      "cleanupStrategy": "lossless",
      "selective": true,
      "sections": [
        "c2pa",
        "id3",
        "xmp",
        "comments",
        "broadcast"
      ],
      "condition": "container-parser",
      "implementation": [
        "app/lib/metadata-cleaner.ts#cleanRiff:wav"
      ],
      "evidence": [
        "source-linked",
        "fixture-confirmed",
        "fixture-pending"
      ]
    },
    {
      "id": "mp3",
      "formats": [
        "MP3"
      ],
      "media": "audio",
      "cleanupStrategy": "lossless",
      "selective": true,
      "sections": [
        "c2pa",
        "id3"
      ],
      "condition": "container-parser",
      "implementation": [
        "app/lib/metadata-cleaner.ts#cleanMp3"
      ],
      "evidence": [
        "source-linked",
        "fixture-confirmed",
        "fixture-pending"
      ]
    },
    {
      "id": "other-image",
      "formats": [
        "AVIF",
        "HEIC",
        "HEIF",
        "TIFF",
        "other readable image"
      ],
      "media": "image",
      "cleanupStrategy": "reencode",
      "selective": false,
      "sections": [],
      "condition": "browser-decoder",
      "implementation": [
        "app/lib/metadata-cleaner.ts#reencodeImage"
      ],
      "evidence": [
        "source-linked",
        "fixture-pending"
      ]
    },
    {
      "id": "other-media",
      "formats": [
        "MP4",
        "MOV",
        "M4A",
        "AAC",
        "FLAC",
        "OGG",
        "Opus",
        "WebM",
        "MKV",
        "AVI",
        "M4V"
      ],
      "media": "audio-video",
      "cleanupStrategy": "remux",
      "selective": false,
      "sections": [],
      "condition": "ffmpeg-support",
      "implementation": [
        "app/lib/metadata-cleaner.ts#cleanMetadata",
        "app/lib/ffmpeg-cleaner.ts#remuxWithoutMetadata"
      ],
      "evidence": [
        "source-linked",
        "fixture-pending"
      ]
    }
  ],
  "inspections": [
    {
      "id": "image-c2pa",
      "scope": "C2PA in SDK-readable images, audio and video",
      "observedFields": [
        "active manifest",
        "claim generator",
        "actions",
        "ingredients",
        "validation state"
      ],
      "implementation": [
        "app/lib/c2pa.ts#inspectC2paForFile",
        "app/lib/c2pa.ts#inspectC2pa"
      ],
      "evidence": [
        "source-linked",
        "external-fixture-confirmed"
      ],
      "limitation": "Cryptographic trust evaluation is disabled; validation is not a truth verdict."
    },
    {
      "id": "media-c2pa-marker",
      "scope": "Fallback C2PA marker scan for SDK-unsupported containers",
      "observedFields": [
        "ASCII marker in the first 16 MiB or last 1 MiB"
      ],
      "implementation": [
        "app/lib/c2pa.ts#inspectMediaC2pa"
      ],
      "evidence": [
        "source-linked",
        "fixture-pending"
      ],
      "limitation": "This is not manifest parsing or signature validation and can miss or over-report markers."
    },
    {
      "id": "editable-profile",
      "scope": "Replacement ordinary metadata profiles in JPEG, PNG, WAV and MP3",
      "observedFields": [
        "XMP",
        "RIFF INFO",
        "ID3v2.3",
        "title",
        "creator",
        "description",
        "rights",
        "software",
        "date"
      ],
      "implementation": [
        "app/lib/metadata-editor-capability.ts",
        "app/lib/metadata-editor.ts",
        "tests/metadata-editor.test.mjs"
      ],
      "evidence": [
        "source-linked",
        "unit-covered",
        "fixture-confirmed",
        "fixture-pending"
      ],
      "limitation": "Editing replaces the named ordinary metadata namespace. ClearTags does not edit or sign C2PA claims."
    },
    {
      "id": "clean-copy-verification",
      "scope": "Post-clean inspection, SHA-256 and media-payload comparison",
      "observedFields": [
        "cleaned metadata",
        "C2PA status",
        "container hash",
        "media-payload hash"
      ],
      "implementation": [
        "app/lib/metadata-verifier.ts",
        "tests/metadata-editor.test.mjs"
      ],
      "evidence": [
        "source-linked",
        "unit-covered",
        "fixture-confirmed",
        "external-fixture-confirmed"
      ],
      "limitation": "Byte-identical media-payload comparison is available only for supported lossless container paths; remuxed or re-encoded output is reported as not comparable."
    },
    {
      "id": "priority-audit",
      "scope": "Readable prompt, workflow and privacy fields",
      "observedFields": [
        "prompt",
        "workflow",
        "seed",
        "location",
        "identity",
        "software"
      ],
      "implementation": [
        "app/lib/metadata-audit.ts",
        "tests/metadata-audit.test.mjs"
      ],
      "evidence": [
        "source-linked",
        "unit-covered",
        "fixture-pending"
      ],
      "limitation": "Field classification is heuristic; the current unit test uses a synthetic parsed report, not an external application file."
    }
  ],
  "fixtures": [
    {
      "id": "jpeg-segments",
      "format": "JPEG",
      "kind": "image",
      "fileName": "cleartags-lab-segments.jpg",
      "mediaDescription": "JPEG start-of-scan through end-of-image bytes",
      "injectedSections": [
        "c2pa",
        "exif",
        "xmp",
        "iptc",
        "comments"
      ],
      "beforeBytes": 423,
      "afterBytes": 205,
      "beforeSha256": "da1bd24660cee3426247dc7f59c0f5195ae0fe10a32afb588d4430bd86deaf3f",
      "afterSha256": "c383c91fe361ec179e2bb1579fe711017eb470c33bb4bd2e1b65a07329ad67fe",
      "mediaPayloadSha256": "f49a148aa9e5ed70c037c73e7876b6467a1a25664cd5612a762e5fe8729078a5",
      "evidence": "fixture-confirmed",
      "fixtureScope": "internal-synthetic-container"
    },
    {
      "id": "png-chunks",
      "format": "PNG",
      "kind": "image",
      "fileName": "cleartags-lab-chunks.png",
      "mediaDescription": "Inflated one-pixel RGBA scanline",
      "injectedSections": [
        "c2pa",
        "exif",
        "xmp",
        "comments",
        "timestamps"
      ],
      "beforeBytes": 279,
      "afterBytes": 73,
      "beforeSha256": "a48c16da20667313c311807b74421b2d0306f941f5ae1c19d1d50b77a3591bf2",
      "afterSha256": "7bf0ec5dcd3059ca8b0e7ec60f4a5a782bec4095720d5d83bac4ac4fae66557d",
      "mediaPayloadSha256": "33c928fc4b5687cd3393e6e8b29256f53e29eca06165a420396e5602de484e2c",
      "evidence": "fixture-confirmed",
      "fixtureScope": "internal-synthetic-container"
    },
    {
      "id": "wav-chunks",
      "format": "WAV",
      "kind": "audio",
      "fileName": "cleartags-lab-chunks.wav",
      "mediaDescription": "Eight unsigned 8-bit PCM samples",
      "injectedSections": [
        "c2pa",
        "id3",
        "xmp",
        "comments",
        "broadcast"
      ],
      "beforeBytes": 236,
      "afterBytes": 52,
      "beforeSha256": "dc614b88e2b9fcb897bd090922a41d9a80b28083420ed71b22e5aa73e6478c08",
      "afterSha256": "bcd4e061b88824d5bc4e09b00d71b36fa1838dfb6435aa05c603b4d9cb8ee01d",
      "mediaPayloadSha256": "e043facf2310145ec8f41eb8c09b90a3ded13bcc4bde860c3988c96f39818a6b",
      "evidence": "fixture-confirmed",
      "fixtureScope": "internal-synthetic-container"
    },
    {
      "id": "mp3-id3",
      "format": "MP3",
      "kind": "audio",
      "fileName": "cleartags-lab-id3.mp3",
      "mediaDescription": "Four MPEG audio frames after the ID3v2 tag",
      "injectedSections": [
        "c2pa",
        "id3"
      ],
      "beforeBytes": 1258,
      "afterBytes": 1152,
      "beforeSha256": "4d007ff2a70d7f0ea755a51582d7947bbc5c96553f0751d216150819dc1034e8",
      "afterSha256": "f54ee9495e2a2411c7261ac9ae7e5bfba57599a8298c52c93b3407c67b70b74d",
      "mediaPayloadSha256": "f54ee9495e2a2411c7261ac9ae7e5bfba57599a8298c52c93b3407c67b70b74d",
      "evidence": "fixture-confirmed",
      "fixtureScope": "internal-synthetic-container"
    }
  ],
  "externalFixtures": [
    {
      "id": "chatgpt-png",
      "format": "PNG",
      "exporter": "ChatGPT / GPT-4o",
      "applicationVersion": "Not provided by upstream",
      "exportSettings": "Generated by ChatGPT; detailed settings not provided by upstream",
      "assetFile": "fixtures/external/contentauth-example-assets/ChatGPT_Image.png",
      "manifestFile": "fixtures/external/contentauth-example-assets/ChatGPT_Image.json",
      "sourceAssetUrl": "https://contentauth.github.io/example-assets/images/ChatGPT_Image.png",
      "sourceManifestUrl": "https://contentauth.github.io/example-assets/images/manifests/ChatGPT_Image.json",
      "sourceRepository": "https://github.com/contentauth/example-assets",
      "license": "MIT",
      "requestedSections": [
        "c2pa",
        "exif",
        "xmp",
        "iptc",
        "comments",
        "timestamps"
      ],
      "beforeBytes": 2130441,
      "afterBytes": 2062529,
      "beforeSha256": "7cd57b4a33f05e4ce7f63de18751f59f4b3ea8c55c281204e0cd6d1f621e466f",
      "afterSha256": "64f6eeb885bbef3ef3cea25708c9277ef5943d57bace687d0bc5fc0ca0691e5c",
      "mediaPayloadSha256": "e745f1a893619fb44aa7902da5df878a37530ba1aa4d8992bf56dba33b584cc4",
      "evidence": "external-fixture-confirmed"
    },
    {
      "id": "firefly-jpeg",
      "format": "JPEG",
      "exporter": "Adobe Firefly",
      "applicationVersion": "4.0.0-release-firefly_v4-main_78135.80468",
      "exportSettings": "text_to_image",
      "assetFile": "fixtures/external/contentauth-example-assets/Firefly_tabby_cat.jpg",
      "manifestFile": "fixtures/external/contentauth-example-assets/Firefly_tabby_cat.json",
      "sourceAssetUrl": "https://contentauth.github.io/example-assets/images/Firefly_tabby_cat.jpg",
      "sourceManifestUrl": "https://contentauth.github.io/example-assets/images/manifests/Firefly_tabby_cat.json",
      "sourceRepository": "https://github.com/contentauth/example-assets",
      "license": "MIT",
      "requestedSections": [
        "c2pa",
        "exif",
        "xmp",
        "iptc",
        "comments"
      ],
      "beforeBytes": 1047024,
      "afterBytes": 920401,
      "beforeSha256": "bdc5c19d4211d9c9f9f8dce5bf4e4dec29e9b32e308ff12a60979481e928154f",
      "afterSha256": "cfe43fc46fe546d560b8b5c8982d1dc02a7ad38b5656a504ca4f738aac777169",
      "mediaPayloadSha256": "cdb85262bc6d355ce4f1b4911869d106dd29d8872bf188237a25fd7125da60b2",
      "evidence": "external-fixture-confirmed"
    },
    {
      "id": "photoshop-jpeg",
      "format": "JPEG",
      "exporter": "Adobe Photoshop",
      "applicationVersion": "26.11.0",
      "exportSettings": "Opened, cropped and resized; other export settings not provided by upstream",
      "assetFile": "fixtures/external/contentauth-example-assets/car-es-Ps-Cr.jpg",
      "manifestFile": "fixtures/external/contentauth-example-assets/car-es-Ps-Cr.json",
      "sourceAssetUrl": "https://contentauth.github.io/example-assets/images/car-es-Ps-Cr.jpg",
      "sourceManifestUrl": "https://contentauth.github.io/example-assets/images/manifests/car-es-Ps-Cr.json",
      "sourceRepository": "https://github.com/contentauth/example-assets",
      "license": "MIT",
      "requestedSections": [
        "c2pa",
        "exif",
        "xmp",
        "iptc",
        "comments"
      ],
      "beforeBytes": 580124,
      "afterBytes": 206038,
      "beforeSha256": "17c9e5b9f40ef79bb8e8af4adf36fe2be54d9c4a7f96f29813e6c3850ab8caa8",
      "afterSha256": "c8245985e01179f9583cc7cd859a9eb6a8f4ddce111e54b58db7dd38beef0f2f",
      "mediaPayloadSha256": "d7362926518ff3f91f286baa321bd8d9a4543bedaf1594470f44f043e88a4cb1",
      "evidence": "external-fixture-confirmed"
    }
  ]
}
