{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://scrollcase.dev/schema/v2/box-manifest.schema.json",
"title": "Box manifest (box.json)",
"description": "The manifest packed inside the archive at box.json. It restates the box's identity, layout and provenance so an extracted box is self-describing: a consumer that has the directory but not the release document can still tell what it is holding and how it was built.",
"type": "object",
"additionalProperties": false,
"required": [
"schemaVersion",
"boxId",
"modelId",
"runtimeId",
"version",
"target",
"pythonEntryPoint",
"modelCacheSubdir",
"selfTest",
"provenance"
],
"properties": {
"schemaVersion": {
"const": 2
},
"boxId": {
"type": "string",
"minLength": 1
},
"modelId": {
"type": "string",
"minLength": 1
},
"runtimeId": {
"type": "string",
"minLength": 1
},
"version": {
"type": "string",
"minLength": 1
},
"target": {
"$ref": "https://scrollcase.dev/schema/v2/target.schema.json"
},
"pythonEntryPoint": {
"type": "string",
"minLength": 1
},
"modelCacheSubdir": {
"type": "string",
"minLength": 1
},
"environment": {
"type": "object",
"description": "Environment variables repeated from the signed release. Scrollcase consumers compare this declaration before execution and apply it over inherited and caller-supplied values.",
"propertyNames": {
"minLength": 1,
"pattern": "^[^=\\u0000]+$"
},
"additionalProperties": {
"type": "string",
"pattern": "^[^\\u0000]*$"
}
},
"selfTest": {
"type": "object",
"additionalProperties": false,
"required": [
"pythonImports",
"timeoutSeconds"
],
"properties": {
"pythonImports": {
"type": "array",
"minItems": 1,
"items": {
"type": "string",
"minLength": 1
}
},
"timeoutSeconds": {
"type": "integer",
"exclusiveMinimum": 0
}
}
},
"execution": {
"$ref": "https://scrollcase.dev/schema/v2/execution.schema.json"
},
"provenance": {
"$ref": "https://scrollcase.dev/schema/v2/release-manifest.schema.json#/$defs/provenance"
},
"weights": {
"const": "on-demand",
"description": "Present only when the assets were deliberately left out of the archive. Absent means the box is self-contained: everything it needs is inside it."
},
"assets": {
"type": "array",
"minItems": 1,
"description": "Assets the consumer must fetch and place under the box root before first use. Present only with on-demand weights. The declared hash is what makes fetching them safe.",
"items": {
"type": "object",
"additionalProperties": false,
"required": [
"url",
"relativePath",
"sizeBytes",
"sha256"
],
"properties": {
"url": {
"type": "string",
"minLength": 1
},
"relativePath": {
"type": "string",
"minLength": 1
},
"sizeBytes": {
"type": "integer",
"exclusiveMinimum": 0
},
"sha256": {
"$ref": "https://scrollcase.dev/schema/v2/release-manifest.schema.json#/$defs/sha256"
}
}
}
}
},
"dependentRequired": {
"assets": [
"weights"
],
"weights": [
"assets"
]
}
}