harn-kernel 0.10.52

Portable compiler, program artifact, and deterministic execution kernel for Harn
Documentation
//! JSON Schema projection of the benchmark receipt contract.
//!
//! The Rust receipt types and validation policy are the semantic owner. The
//! CLI writes this projection to `spec/schemas/`; consumers never maintain a
//! second hand-authored schema.

use serde_json::{json, Value};

use super::{
    PORTABLE_BENCHMARK_SCHEMA_VERSION, PORTABLE_MAX_COMPILE_ITERATIONS,
    PORTABLE_MAX_DISPATCH_ITERATIONS, PORTABLE_MAX_WORKERS,
};

/// Generate the public JSON Schema for [`super::PortableBenchmarkReceipt`].
pub fn portable_benchmark_json_schema() -> Value {
    json!({
      "$schema": "https://json-schema.org/draft/2020-12/schema",
      "$id": "https://harnlang.com/schemas/portable-kernel-benchmark.v1.schema.json",
      "$comment": "Generated by `make gen-portable-benchmark-schema`; do not edit by hand.",
      "title": "Harn Portable Kernel benchmark receipt v1",
      "type": "object",
      "additionalProperties": false,
      "required": [
        "schemaVersion", "target", "source", "entry", "entryKind",
        "artifactBytes", "artifactDigest", "iterations", "workers",
        "provenance", "initializationMs", "compile", "decode", "dispatch",
        "terminalDigest"
      ],
      "properties": {
        "schemaVersion": { "const": PORTABLE_BENCHMARK_SCHEMA_VERSION },
        "target": { "enum": ["native", "browser"] },
        "source": { "type": "string", "minLength": 1 },
        "entry": { "type": "string", "minLength": 1 },
        "entryKind": { "enum": ["function", "pipeline"] },
        "artifactBytes": { "type": "integer", "minimum": 1 },
        "artifactDigest": { "$ref": "#/$defs/digest" },
        "iterations": {
          "type": "integer", "minimum": 1,
          "maximum": PORTABLE_MAX_DISPATCH_ITERATIONS
        },
        "workers": {
          "type": "integer", "minimum": 1, "maximum": PORTABLE_MAX_WORKERS
        },
        "provenance": { "$ref": "#/$defs/provenance" },
        "initializationMs": { "type": ["number", "null"], "minimum": 0 },
        "compile": { "$ref": "#/$defs/compileMeasurements" },
        "decode": {
          "oneOf": [
            { "$ref": "#/$defs/compileStatistics" },
            { "type": "null" }
          ]
        },
        "dispatch": { "$ref": "#/$defs/dispatchMeasurements" },
        "terminalDigest": { "$ref": "#/$defs/digest" }
      },
      "$defs": {
        "digest": { "type": "string", "pattern": "^[0-9a-f]{64}$" },
        "provenance": {
          "type": "object",
          "additionalProperties": false,
          "required": [
            "harnVersion", "kernelVersion", "artifactFormatVersion",
            "semanticAbiFingerprint", "opcodeAbiFingerprint", "buildProfile",
            "os", "arch"
          ],
          "properties": {
            "harnVersion": { "type": "string", "minLength": 1 },
            "kernelVersion": { "type": "string", "minLength": 1 },
            "artifactFormatVersion": { "type": "integer", "minimum": 1 },
            "semanticAbiFingerprint": { "$ref": "#/$defs/digest" },
            "opcodeAbiFingerprint": { "$ref": "#/$defs/digest" },
            "buildProfile": { "enum": ["debug", "release"] },
            "os": { "type": "string", "minLength": 1 },
            "arch": { "type": "string", "minLength": 1 }
          }
        },
        "statistics": {
          "type": "object",
          "additionalProperties": false,
          "required": [
            "iterations", "min_ms", "mean_ms", "p50_ms", "p95_ms",
            "max_ms", "stddev_ms", "total_ms"
          ],
          "properties": {
            "iterations": { "type": "integer", "minimum": 1 },
            "min_ms": { "type": "number", "minimum": 0 },
            "mean_ms": { "type": "number", "minimum": 0 },
            "p50_ms": { "type": "number", "minimum": 0 },
            "p95_ms": { "type": "number", "minimum": 0 },
            "max_ms": { "type": "number", "minimum": 0 },
            "stddev_ms": { "type": "number", "minimum": 0 },
            "total_ms": { "type": "number", "minimum": 0 }
          }
        },
        "compileStatistics": {
          "allOf": [
            { "$ref": "#/$defs/statistics" },
            { "properties": { "iterations": {
              "maximum": PORTABLE_MAX_COMPILE_ITERATIONS
            } } }
          ]
        },
        "dispatchStatistics": {
          "allOf": [
            { "$ref": "#/$defs/statistics" },
            { "properties": { "iterations": {
              "maximum": PORTABLE_MAX_DISPATCH_ITERATIONS
            } } }
          ]
        },
        "compileMeasurements": {
          "type": "object",
          "additionalProperties": false,
          "required": ["firstMs", "repeated"],
          "properties": {
            "firstMs": { "type": "number", "minimum": 0 },
            "repeated": { "$ref": "#/$defs/compileStatistics" }
          }
        },
        "dispatchMeasurements": {
          "type": "object",
          "additionalProperties": false,
          "required": [
            "firstMs", "repeated", "batchWallMs", "throughputPerSecond"
          ],
          "properties": {
            "firstMs": { "type": "number", "minimum": 0 },
            "repeated": { "$ref": "#/$defs/dispatchStatistics" },
            "batchWallMs": { "type": "number", "exclusiveMinimum": 0 },
            "throughputPerSecond": { "type": "number", "exclusiveMinimum": 0 }
          }
        }
      }
    })
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn schema_projects_owned_limits_and_receipt_fields() {
        let schema = portable_benchmark_json_schema();
        assert_eq!(
            schema["properties"]["schemaVersion"]["const"],
            PORTABLE_BENCHMARK_SCHEMA_VERSION
        );
        assert_eq!(
            schema["properties"]["iterations"]["maximum"],
            PORTABLE_MAX_DISPATCH_ITERATIONS
        );
        assert_eq!(
            schema["properties"]["workers"]["maximum"],
            PORTABLE_MAX_WORKERS
        );
        let required = schema["required"].as_array().expect("required fields");
        let properties = schema["properties"].as_object().expect("properties");
        assert_eq!(required.len(), properties.len());
        assert!(properties.keys().all(|key| required.contains(&json!(key))));
    }
}