← Files Email LoveARCHIVED FILE

skills/email-love-figma-quality-gates/references/snapshot-schema.md

5.54 KB · Oct 4, 2026 · 12:29 UTC

↓ Download file

# Audit snapshot schema

## Contents

- Example snapshot
- Batch fields
- Module fields

The validator accepts one JSON object with `batch` and `modules`. Keep measurements numeric
and in email pixels.

## Example

```json
{
  "batch": {
    "name": "Proof batch 01",
    "phase": "proof",
    "emailWidth": 600,
    "contentWidth": 520,
    "mobileViewports": [320, 375, 390],
    "riskClassesPresent": ["grouped-icon-text"],
    "proofRisksCovered": ["grouped-icon-text"],
    "proofBatchAccepted": false,
    "statusClaim": "canvas and structure ready, exporter verification deferred",
    "exporter": {
      "desktop": "deferred",
      "mobile": "deferred"
    }
  },
  "modules": [
    {
      "id": "12:34",
      "name": "Benefits, image top + icon rows",
      "sourceRef": "Source screenshot 03 / benefits band",
      "sourceParity": {
        "content": true,
        "order": true,
        "crop": true,
        "type": true,
        "color": true,
        "spacing": true,
        "desktop": true,
        "mobileIntent": true
      },
      "structure": {
        "rootTag": "mj-wrapper",
        "nodeType": "",
        "directPageChild": true,
        "untaggedFrameCount": 0,
        "unknownTagCount": 0,
        "incompleteLeafPairCount": 0,
        "unequalAxisCount": 0,
        "axisExceptions": [],
        "unintendedFixedHeightCount": 0
      },
      "census": {"images": 1, "groups": 1, "properties": 2},
      "images": [
        {
          "name": "Feature icon / sparkle",
          "role": "icon",
          "meaningful": true,
          "fillType": "IMAGE",
          "imageHash": "abc123",
          "scaleMode": "FILL",
          "rectWidth": 32,
          "rectHeight": 32,
          "assetWidth": 64,
          "assetHeight": 64,
          "cropApproved": false,
          "altText": "Odor filtration"
        }
      ],
      "groups": [
        {
          "name": "Feature row 1",
          "width": 520,
          "mobileSectionPaddingLeft": 40,
          "mobileSectionPaddingRight": 40,
          "columns": [
            {
              "name": "Icon column",
              "width": 96,
              "paddingLeft": 0,
              "paddingRight": 10,
              "content": {
                "kind": "image",
                "naturalWidth": 32
              }
            },
            {
              "name": "Text column",
              "width": 424,
              "paddingLeft": 16,
              "paddingRight": 0,
              "content": {
                "kind": "text",
                "longestUnbreakablePx": 90
              }
            }
          ]
        }
      ],
      "properties": [
        {
          "name": "Headline",
          "type": "TEXT",
          "evidence": "Changes between campaigns",
          "bindingCount": 1,
          "boilerplate": false,
          "linkBearing": false
        },
        {
          "name": "Show Feature Row 3",
          "type": "BOOLEAN",
          "evidence": "Source family includes a two-row version",
          "bindingCount": 1,
          "hideScope": "complete-region",
          "remainingLayoutComplete": true,
          "ancestorRequiredFixedColumn": false
        }
      ]
    }
  ]
}
```

## Batch fields

- `phase`: `proof` or `normal`.
- `mobileViewports`: target widths used for every group ledger.
- `riskClassesPresent`: any of `photo-crop`, `grouped-icon-text`,
  `multi-column-properties`, and `footer-social` found in the source inventory.
- `proofRisksCovered`: risk classes represented by the chosen proof modules.
- `proofBatchAccepted`: required and `true` for a normal batch.
- `statusClaim`: one of the four states defined by the skill.
- `exporter.desktop` and `exporter.mobile`: `pass`, `fail`, or `deferred`.

A proof batch has at most four modules. A `complete` claim requires desktop and mobile
`pass`. A normal batch cannot validate until the proof batch is accepted.

## Module fields

- `sourceRef` identifies an exact source screenshot, email, or frame region.
- `sourceParity` contains every comparison dimension shown above.
- `structure` contains measured counts, not checklist prose.
- `structure.axisExceptions` lists documented render-contract exceptions for unequal
  auto-layout axes, one `{"node", "reason"}` object each; the only allowed reason today is
  `top-aligned-multi-column`. `unequalAxisCount` may not exceed the number of valid
  exceptions.
- `census` is the independently measured node census: how many meaningful images, groups,
  and properties the module's node tree actually contains. Each inventory array must match
  its census count, so an empty array cannot conceal real content. The `images`, `groups`,
  and `properties` arrays are REQUIRED even when audited empty; omitting one is absent
  evidence and fails validation. A measurement recorded as anything other than a finite
  number (an "unknown" string, null, a negative) also fails; the validator never substitutes
  zero.
- `images` contains one record per meaningful image, icon, or social mark.
- `groups` contains every `mj-group` that must remain side by side on mobile.
  A fixed bordered group whose columns deliberately sum short of the outer width declares
  the gap as `borderHeadroom` (px) with a `headroomReason`; an undeclared gap fails.
- `properties` contains every component property, including fixed TEXT and zero BOOLEAN cases.

`longestUnbreakablePx` must be measured against the exported font stack, not the Figma canvas
font. `naturalWidth` is the minimum rendered width an image needs to remain unshrunk; it is
not automatically the source file's pixel width when a 2x asset is intentionally displayed
at half size.

SHA-256: 5971f7944815612e38e86513da5cbbab3c969e28b607e3b201c68cb97efc4ee3