{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://catalog.lintel.tools/schemas/schemastore/spack-concretizer-yaml/latest.json",
  "title": "Spack concretizer configuration file schema",
  "x-lintel": {
    "source": "https://raw.githubusercontent.com/spack/schemas/refs/heads/main/schemas/concretizer.json",
    "sourceSha256": "73b626bb245aaed4734b4912cbf1272af9d6bf6b01d6bdd463731c447cd5651c",
    "fileMatch": [
      "**/*spack/**/concretizer.yaml"
    ],
    "parsers": [
      "yaml"
    ]
  },
  "type": "object",
  "properties": {
    "concretizer": {
      "type": "object",
      "properties": {
        "force": {
          "type": "boolean",
          "default": false,
          "description": "Force re-concretization when concretizing environments"
        },
        "reuse": {
          "description": "Controls how aggressively Spack reuses installed packages and build caches during concretization",
          "oneOf": [
            {
              "type": "boolean",
              "description": "If true, reuse installed packages and build caches for all specs; if false, always perform fresh concretization"
            },
            {
              "type": "string",
              "enum": [
                "dependencies"
              ],
              "description": "Reuse installed packages and build caches only for dependencies, not root specs"
            },
            {
              "type": "object",
              "description": "Advanced reuse configuration with fine-grained control over which specs are reused",
              "properties": {
                "roots": {
                  "type": "boolean",
                  "description": "If true, root specs are reused; if false, only dependencies of root specs are reused"
                },
                "include": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  },
                  "description": "List of spec constraints. Reusable specs must match at least one constraint"
                },
                "exclude": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  },
                  "description": "List of spec constraints. Reusable specs must not match any constraint"
                },
                "from": {
                  "type": "array",
                  "description": "List of sources from which reused specs are taken",
                  "items": {
                    "type": "object",
                    "description": "Source configuration for reusable specs",
                    "properties": {
                      "type": {
                        "type": "string",
                        "enum": [
                          "local",
                          "buildcache",
                          "external",
                          "environment"
                        ],
                        "description": "Type of source: 'local' (installed packages), 'buildcache' (remote binaries), 'external' (system packages), or 'environment' (from specific environment)"
                      },
                      "path": {
                        "type": "string",
                        "description": "Path to the source (for environment type sources)"
                      },
                      "include": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        },
                        "description": "Spec constraints that must be matched for this source (overrides global include)"
                      },
                      "exclude": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        },
                        "description": "Spec constraints that must not be matched for this source (overrides global exclude)"
                      }
                    }
                  }
                }
              }
            }
          ]
        },
        "enable_node_namespace": {
          "type": "boolean",
          "description": "Enable node namespace functionality in the concretizer"
        },
        "targets": {
          "type": "object",
          "description": "Controls which target microarchitectures are considered during concretization",
          "properties": {
            "host_compatible": {
              "type": "boolean",
              "description": "If true, only allow targets compatible with the current host; if false, allow any target (e.g., concretize for icelake while running on haswell)"
            },
            "granularity": {
              "type": "string",
              "enum": [
                "generic",
                "microarchitectures"
              ],
              "description": "Target selection granularity: 'microarchitectures' (e.g., haswell, skylake) or 'generic' (e.g., x86_64_v3, aarch64)"
            }
          }
        },
        "unify": {
          "description": "Controls whether environment specs are concretized together or separately",
          "oneOf": [
            {
              "type": "boolean",
              "description": "If true, concretize environment root specs together for unified dependencies; if false, concretize each spec independently"
            },
            {
              "type": "string",
              "enum": [
                "when_possible"
              ],
              "description": "Maximizes reuse, while allowing multiple instances of the same package"
            }
          ]
        },
        "compiler_mixing": {
          "oneOf": [
            {
              "type": "boolean"
            },
            {
              "type": "array"
            }
          ],
          "description": "Whether to allow compiler mixing between link/run dependencies"
        },
        "splice": {
          "type": "object",
          "properties": {
            "explicit": {
              "type": "array",
              "default": [],
              "description": "List of explicit splice configurations to replace specific dependencies",
              "items": {
                "type": "object",
                "required": [
                  "target",
                  "replacement"
                ],
                "properties": {
                  "target": {
                    "type": "string",
                    "description": "Abstract spec to be replaced (e.g., 'mpi' or specific package)"
                  },
                  "replacement": {
                    "type": "string",
                    "description": "Concrete spec with hash to use as replacement (e.g., 'mpich/abcdef')"
                  },
                  "transitive": {
                    "type": "boolean",
                    "default": false,
                    "description": "If true, use transitive splice (conflicts resolved using replacement dependencies); if false, use intransitive splice (conflicts resolved using original dependencies)"
                  }
                },
                "description": "Explicit splice configuration",
                "additionalProperties": false
              }
            },
            "automatic": {
              "type": "boolean",
              "description": "Enable automatic splicing for ABI-compatible packages (experimental feature)"
            }
          },
          "description": "Configuration for spec splicing: replacing dependencies with ABI-compatible alternatives to improve package reuse",
          "additionalProperties": false
        },
        "duplicates": {
          "type": "object",
          "description": "Controls whether the dependency graph can contain multiple configurations of the same package",
          "properties": {
            "strategy": {
              "type": "string",
              "enum": [
                "none",
                "minimal",
                "full"
              ],
              "description": "Duplication strategy: 'none' (single config per package), 'minimal' (allow build-tools duplicates), 'full' (experimental: allow full build-tool stack separation)"
            },
            "max_dupes": {
              "type": "object",
              "description": "Maximum number of duplicates allowed per package when using strategies that permit duplicates",
              "additionalProperties": {
                "type": "integer",
                "minimum": 1,
                "description": "Maximum number of duplicate instances for this package"
              }
            }
          }
        },
        "static_analysis": {
          "type": "boolean",
          "description": "Enable static analysis to reduce concretization time by generating smaller ASP problems"
        },
        "timeout": {
          "type": "integer",
          "minimum": 0,
          "description": "Maximum time in seconds for the solve phase (0 means no time limit)"
        },
        "error_on_timeout": {
          "type": "boolean",
          "description": "If true, timeout always results in error; if false, use best suboptimal solution found before timeout (yields unreproducible results)"
        },
        "os_compatible": {
          "type": "object",
          "description": "Compatibility mapping between operating systems for reuse of compilers and packages (key: target OS, value: list of compatible source OSes)",
          "additionalProperties": {
            "type": "array"
          }
        },
        "concretization_cache": {
          "type": "object",
          "description": "Configuration for caching solver outputs from successful concretization runs",
          "properties": {
            "enable": {
              "type": "boolean",
              "description": "Whether to utilize a cache of solver outputs from successful concretization runs"
            },
            "url": {
              "type": "string",
              "description": "Path to the location where Spack will root the concretization cache"
            },
            "entry_limit": {
              "type": "integer",
              "minimum": 0,
              "description": "Limit on the number of concretization results that Spack will cache (0 disables pruning)"
            }
          }
        },
        "externals": {
          "type": "object",
          "description": "Configuration for how Spack handles external packages during concretization",
          "properties": {
            "completion": {
              "type": "string",
              "enum": [
                "architecture_only",
                "default_variants"
              ],
              "description": "Controls how missing information (variants, etc.) is completed for external packages: 'architecture_only' completes only mandatory architectural information; 'default_variants' also completes missing variants using their default values"
            }
          }
        }
      },
      "description": "Concretizer configuration that controls dependency selection, package reuse, and solver behavior",
      "additionalProperties": false
    }
  },
  "additionalProperties": false
}
