jevrecipes

Recipe catalog / privacy-notice-facets

Label the statements in a privacy notice

Which of these does notice state: what data is collected, why it is used, how long it is kept, who it is shared with, how to contact the controller?

You need several independent yes/no checks on a privacy notice in one call, to spot missing statements before a review or publication.

Explore this recipe interactively ยท Source and implementation guide

Use privacy-notice-facets in TypeScript

Install with npm install jev-recipes. Requires Node.js 22.9 or newer and ES modules. Set TYPESAFE_API_KEY in your server environment for live calls, which send input to TypeSafe and use API quota. See the installation guide.

import { privacyNoticeFacets } from 'jev-recipes/privacy-notice-facets';

const result = await privacyNoticeFacets({
  "notice": "When you create an account we collect your name, email address, and billing details. We use this information to provide the service, process payments, and send account notices. We share billing details with our payment processor and do not sell your data. Questions about your data can be sent to [email protected].",
  "minConfidence": 0.8
});
console.log(result);

Input contract

FieldTypeNeeded
noticestringRequired
minConfidencenumberOptional
Full input and result schemas
{
  "input": {
    "$schema": "https://json-schema.org/draft/2020-12/schema",
    "type": "object",
    "properties": {
      "notice": {
        "type": "string"
      },
      "minConfidence": {
        "type": "number",
        "minimum": 0,
        "maximum": 1
      }
    },
    "required": [
      "notice"
    ]
  },
  "result": {
    "$schema": "https://json-schema.org/draft/2020-12/schema",
    "type": "object",
    "properties": {
      "model": {
        "type": "string"
      },
      "usage": {
        "type": "object",
        "properties": {
          "input_tokens": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991
          },
          "output_tokens": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991
          }
        },
        "required": [
          "input_tokens",
          "output_tokens"
        ],
        "additionalProperties": false
      },
      "status": {
        "type": "string",
        "enum": [
          "ready",
          "review"
        ]
      },
      "detected": {
        "type": "array",
        "items": {
          "type": "string",
          "enum": [
            "statesDataCollected",
            "statesPurpose",
            "statesRetention",
            "statesSharing",
            "statesContact"
          ]
        }
      },
      "labels": {
        "type": "object",
        "properties": {
          "statesDataCollected": {
            "type": "object",
            "properties": {
              "status": {
                "type": "string",
                "enum": [
                  "ready",
                  "review"
                ]
              },
              "verdict": {
                "type": "string",
                "enum": [
                  "present",
                  "absent"
                ]
              },
              "probability": {
                "type": "number",
                "minimum": 0,
                "maximum": 1
              },
              "confidence": {
                "type": "number",
                "minimum": 0,
                "maximum": 1
              }
            },
            "required": [
              "status",
              "verdict",
              "probability",
              "confidence"
            ],
            "additionalProperties": false
          },
          "statesPurpose": {
            "type": "object",
            "properties": {
              "status": {
                "type": "string",
                "enum": [
                  "ready",
                  "review"
                ]
              },
              "verdict": {
                "type": "string",
                "enum": [
                  "present",
                  "absent"
                ]
              },
              "probability": {
                "type": "number",
                "minimum": 0,
                "maximum": 1
              },
              "confidence": {
                "type": "number",
                "minimum": 0,
                "maximum": 1
              }
            },
            "required": [
              "status",
              "verdict",
              "probability",
              "confidence"
            ],
            "additionalProperties": false
          },
          "statesRetention": {
            "type": "object",
            "properties": {
              "status": {
                "type": "string",
                "enum": [
                  "ready",
                  "review"
                ]
              },
              "verdict": {
                "type": "string",
                "enum": [
                  "present",
                  "absent"
                ]
              },
              "probability": {
                "type": "number",
                "minimum": 0,
                "maximum": 1
              },
              "confidence": {
                "type": "number",
                "minimum": 0,
                "maximum": 1
              }
            },
            "required": [
              "status",
              "verdict",
              "probability",
              "confidence"
            ],
            "additionalProperties": false
          },
          "statesSharing": {
            "type": "object",
            "properties": {
              "status": {
                "type": "string",
                "enum": [
                  "ready",
                  "review"
                ]
              },
              "verdict": {
                "type": "string",
                "enum": [
                  "present",
                  "absent"
                ]
              },
              "probability": {
                "type": "number",
                "minimum": 0,
                "maximum": 1
              },
              "confidence": {
                "type": "number",
                "minimum": 0,
                "maximum": 1
              }
            },
            "required": [
              "status",
              "verdict",
              "probability",
              "confidence"
            ],
            "additionalProperties": false
          },
          "statesContact": {
            "type": "object",
            "properties": {
              "status": {
                "type": "string",
                "enum": [
                  "ready",
                  "review"
                ]
              },
              "verdict": {
                "type": "string",
                "enum": [
                  "present",
                  "absent"
                ]
              },
              "probability": {
                "type": "number",
                "minimum": 0,
                "maximum": 1
              },
              "confidence": {
                "type": "number",
                "minimum": 0,
                "maximum": 1
              }
            },
            "required": [
              "status",
              "verdict",
              "probability",
              "confidence"
            ],
            "additionalProperties": false
          }
        },
        "required": [
          "statesDataCollected",
          "statesPurpose",
          "statesRetention",
          "statesSharing",
          "statesContact"
        ],
        "additionalProperties": false
      }
    },
    "required": [
      "model",
      "usage",
      "status",
      "detected",
      "labels"
    ],
    "additionalProperties": false
  }
}

Saved example result

This hand-authored response demonstrates the contract. It is not a model accuracy measurement. Run it without an API key: npx jev-recipes demo privacy-notice-facets.

{
  "model": "demo-fixture",
  "usage": {
    "input_tokens": 0,
    "output_tokens": 0
  },
  "status": "ready",
  "detected": [
    "statesDataCollected",
    "statesPurpose",
    "statesSharing",
    "statesContact"
  ],
  "labels": {
    "statesDataCollected": {
      "status": "ready",
      "verdict": "present",
      "probability": 0.97,
      "confidence": 0.97
    },
    "statesPurpose": {
      "status": "ready",
      "verdict": "present",
      "probability": 0.95,
      "confidence": 0.95
    },
    "statesRetention": {
      "status": "ready",
      "verdict": "absent",
      "probability": 0.04,
      "confidence": 0.96
    },
    "statesSharing": {
      "status": "ready",
      "verdict": "present",
      "probability": 0.93,
      "confidence": 0.93
    },
    "statesContact": {
      "status": "ready",
      "verdict": "present",
      "probability": 0.96,
      "confidence": 0.96
    }
  }
}

Evaluation evidence

Fixture only

No verified live accuracy measurement is available. Evaluate representative cases before using this decision in your workflow.

Use the evaluation guide to measure this decision on your own labeled cases.

Limitations

Related recipes