{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "title": "Artifact Acceptance Criteria",
  "description": "What a dataset has to satisfy to serve as a given artifact: the variable it must carry, the units that variable may be in, the axes it must have, the grids it may be on, and any schema it must conform to.\n**This is what makes `replace-with-local-equivalent` actionable.** That action is by far the most common in the FOCAL corpus, and on its own it says that something must change without saying what would count as having changed it correctly. A platform asked \"can I run this workflow over my area of interest with my data?\" cannot answer from the action alone. It can answer from these criteria, against a candidate file, with no human in the loop.\n**These are properties of the artifact, not of the transfer.** UP-WF3's precipitation input needs millimetres or kg m\u207b\u00b2s\u207b\u00b9 and a time axis whether or not anyone is moving the workflow anywhere; the requirement simply becomes visible when a substitution is proposed. So the criteria attach to the artifact declaration, where they are stated once, rather than to the rules that happen to invoke them. A rule saying `replace-with-local-equivalent` cites the artifact by id, and the criteria travel with it.\nEvery property is optional and at least one is required: a criteria object that only carries a note states no criterion. Where a requirement genuinely resists structuring, say it in `transferabilityNotes` rather than inventing a property for it.\n**Published vocabularies, not FOCAL ones, wherever one exists.** Units are QUDT unit IRIs (`MilliM`, `KiloGM-PER-M2-SEC`, whose QUDT symbols are exactly the `mm` and `kg/(m\u00b2\u00b7s)` UP-WF3 states). A schema requirement is `dcterms:conformsTo`. Grid types are the same FOCAL scheme bblocks://ogc.focal.transferability.envelopeConstraint uses, cross-walked to CF `grid_mapping_name`. Only `variable` and `axes` are FOCAL's own, and only because a workflow's internal expectation of what an input is called is not a published fact about anything.\n**Evidenced 2/8:** UP-WF3 states the fullest contract in the corpus (variable name, either of two units, a time axis, one of two grids); UP-WF2's planned Eurostat input states a schema compatibility preference. Expect this to grow: the question was never asked in the questionnaires, so absence here is not evidence that other workflows have no contract.\n",
  "allOf": [
    {
      "$ref": "https://ogcincubator.github.io/bblocks-focal/build/annotated/focal/transferability/notes/schema.json"
    },
    {
      "type": "object",
      "anyOf": [
        {
          "required": [
            "variable"
          ]
        },
        {
          "required": [
            "units"
          ]
        },
        {
          "required": [
            "axes"
          ]
        },
        {
          "required": [
            "gridTypes"
          ]
        },
        {
          "required": [
            "conformsTo"
          ]
        }
      ],
      "properties": {
        "variable": {
          "oneOf": [
            {
              "type": "string",
              "examples": [
                "pr",
                "rr"
              ]
            },
            {
              "type": "object",
              "title": "Same as the current artifact",
              "required": [
                "sameAsCurrent"
              ],
              "additionalProperties": false,
              "properties": {
                "sameAsCurrent": {
                  "const": true,
                  "x-jsonld-id": "https://w3id.org/ogc/hosted/focal/transferability/properties/sameAsCurrent"
                }
              }
            }
          ],
          "description": "The name the workflow expects the variable to be called, either as a literal or as a relation to whatever the artifact currently in use carries.\n**The relation form is not a fallback for not knowing.** UP-WF3's source says a replacement must have *\"the same precipitation variable name as current dataset\"*, and that is a complete, precise requirement stated as a relation. Recording a literal in its place (`rr`, say, guessed from the fact that one of the two current sources is E-OBS) asserts something the source did not, and is wrong outright if the workflow reads the CORDEX path where the same field is called `pr`. `{\"sameAsCurrent\": true}` states exactly the requirement, and a platform can evaluate it by reading the artifact in use. Use it when sameness *is* the claim; where the source names a value, name the value.\nA plain string rather than a term, deliberately. The obvious binding is a CF standard name (`precipitation_amount`), and a CF standard name is not what a NetCDF variable is called; the two coincide only by convention. Recording the actual name keeps the check honest. If a workflow owner supplies a standard name as well, that is a second fact and wants its own property, not a reinterpretation of this one.\n",
          "x-jsonld-id": "https://w3id.org/ogc/hosted/focal/transferability/properties/variable"
        },
        "units": {
          "type": "array",
          "minItems": 1,
          "items": {
            "type": "string",
            "examples": [
              "MilliM",
              "KiloGM-PER-M2-SEC"
            ]
          },
          "description": "The units the variable may be in, as QUDT unit IRIs (relative names resolve against `http://qudt.org/vocab/unit/`). **An OR-set:** any one is acceptable, which is UP-WF3's case exactly \u2014 millimetres or kg m\u207b\u00b2s\u207b\u00b9, the accumulated and the flux form of the same quantity.\nQUDT rather than a unit string, because `mm`, `millimetre` and `mm/day` are three incomparable strings and one of them is a different quantity. QUDT carries the symbol and the quantity kind, so a consumer can tell that a candidate in `kg/(m\u00b2\u00b7s)` satisfies this and one in metres does not.\n",
          "x-jsonld-id": "https://w3id.org/ogc/hosted/focal/transferability/properties/unit",
          "x-jsonld-type": "@id",
          "x-jsonld-container": "@set",
          "x-jsonld-base": "http://qudt.org/vocab/unit/"
        },
        "axes": {
          "type": "array",
          "minItems": 1,
          "items": {
            "type": "string",
            "examples": [
              "time"
            ]
          },
          "description": "Axes the data must have, as concepts from the FOCAL axes scheme (see bblocks://ogc.focal.transferability.vocab). **Conjunctive**, unlike `units` and `gridTypes`: every axis listed must be present. UP-WF3 requires a time axis, without which its rolling accumulation has nothing to accumulate over.\n",
          "x-jsonld-id": "https://w3id.org/ogc/hosted/focal/transferability/properties/axis",
          "x-jsonld-type": "@id",
          "x-jsonld-container": "@set",
          "x-jsonld-base": "https://w3id.org/ogc/hosted/focal/transferability/axes/"
        },
        "gridTypes": {
          "type": "array",
          "minItems": 1,
          "items": {
            "type": "string",
            "examples": [
              "regular-latlon",
              "rotated-pole"
            ]
          },
          "description": "The grids the data may be on, from the same open scheme an envelope constraint's `grid-structure` dimension uses. **An OR-set.**\nNot a duplicate of that dimension: the two do different jobs. An envelope constraint is a boundary a *rule is conditioned on* \u2014 cite it in `when` and the rule fires when the target falls outside it. These criteria are a specification a *candidate is checked against* once the rule has already fired and says to substitute something. State the constraint at the envelope when it bounds the workflow as a whole, and here when it binds this one artifact; UP-WF3 happens to be a case where both readings are available, because its only gridded input is also the whole of its gridded interface.\n",
          "x-jsonld-id": "https://w3id.org/ogc/hosted/focal/transferability/properties/gridType",
          "x-jsonld-type": "@id",
          "x-jsonld-container": "@set",
          "x-jsonld-base": "https://w3id.org/ogc/hosted/focal/transferability/grid-types/"
        },
        "conformsTo": {
          "type": "array",
          "minItems": 1,
          "items": {
            "$ref": "https://opengeospatial.github.io/bblocks/annotated-schemas/ogc-utils/iri-or-curie/schema.json"
          },
          "description": "Schemas or specifications the data must conform to, as identifiers. Uplifts to `dcterms:conformsTo`, the term catalogues already use for exactly this.\nUP-WF2's planned Heat Risk Indicator is the evidenced case: replacement census data \"preferably following a schema compatible with Eurostat's\". Note that source says *preferably*, so recording it here states it more firmly than the questionnaire does \u2014 which is a thing to check with the owner rather than to smooth over. Where the preference is genuinely soft, `transferabilityNotes` is the honest home for it.\n",
          "x-jsonld-id": "http://purl.org/dc/terms/conformsTo",
          "x-jsonld-type": "@id",
          "x-jsonld-container": "@set"
        },
        "transferabilityNotes": {
          "type": "string",
          "description": "A requirement that does not reduce to the properties above, or a qualification on one that does. Uplifts to `rdfs:comment`. Mixed in from bblocks://ogc.focal.transferability.notes. Not a criterion on its own: a criteria object needs at least one structured property.\n",
          "x-jsonld-id": "http://www.w3.org/2000/01/rdf-schema#comment"
        }
      }
    }
  ],
  "x-jsonld-prefixes": {
    "focal-transf-prop": "https://w3id.org/ogc/hosted/focal/transferability/properties/",
    "dcterms": "http://purl.org/dc/terms/",
    "rdfs": "http://www.w3.org/2000/01/rdf-schema#"
  }
}