build(agent): weasel-1#856f80 iteration
This commit is contained in:
parent
22c31fc61a
commit
3e7e7af678
|
|
@ -0,0 +1,14 @@
|
||||||
|
{
|
||||||
|
"contract_id": "example-contract-001",
|
||||||
|
"version": "1.0",
|
||||||
|
"local_capabilities": [
|
||||||
|
{ "name": "Planner", "capabilities": ["plan", "optimize"], "metadata": {"vendor": "example"} }
|
||||||
|
],
|
||||||
|
"pre_conditions": { "description": "start in safe state", "conditions": {"battery": ">=50"} },
|
||||||
|
"post_conditions": { "description": "end in safe state", "conditions": {"docked": true} },
|
||||||
|
"budgets": { "cpu_cores": 2.0, "memory_gb": 4.0, "energy_wh": 200.0, "time_seconds": 3600 },
|
||||||
|
"data_policy": { "policy_id": "policy-example", "allowed_data": ["telemetry"], "constraints": {} },
|
||||||
|
"scenarios": [
|
||||||
|
{ "scenario_id": "sc-01", "deterministic_replay": true, "seed": 42, "description": "sensor dropout mid-mission", "sensors": {"camera": {"fps": 10}}, "environment": {"dust": "high"} }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
@ -8,7 +8,10 @@ version = "0.1.0"
|
||||||
description = "Modular framework for certification, benchmarking and governance of onboard AI in space robotics. MVP scaffold."
|
description = "Modular framework for certification, benchmarking and governance of onboard AI in space robotics. MVP scaffold."
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
requires-python = ">=3.8"
|
requires-python = ">=3.8"
|
||||||
license = { text = "MIT" }
|
license = "MIT"
|
||||||
|
dependencies = [
|
||||||
|
"jsonschema>=4.0.0"
|
||||||
|
]
|
||||||
authors = [ { name = "OpenCode Collaboration" } ]
|
authors = [ { name = "OpenCode Collaboration" } ]
|
||||||
|
|
||||||
[project.urls]
|
[project.urls]
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,70 @@
|
||||||
|
{
|
||||||
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||||
|
"$id": "https://example.org/schemas/spacesafeml/safety_contract.json",
|
||||||
|
"title": "SafetyContract",
|
||||||
|
"type": "object",
|
||||||
|
"required": ["contract_id", "local_capabilities"],
|
||||||
|
"properties": {
|
||||||
|
"contract_id": { "type": "string" },
|
||||||
|
"version": { "type": "string", "default": "1.0" },
|
||||||
|
"local_capabilities": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "object",
|
||||||
|
"required": ["name"],
|
||||||
|
"properties": {
|
||||||
|
"name": { "type": "string" },
|
||||||
|
"capabilities": { "type": "array", "items": { "type": "string" } },
|
||||||
|
"metadata": { "type": "object" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"pre_conditions": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"description": { "type": "string" },
|
||||||
|
"conditions": { "type": "object" }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"post_conditions": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"description": { "type": "string" },
|
||||||
|
"conditions": { "type": "object" }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"budgets": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"cpu_cores": { "type": "number" },
|
||||||
|
"memory_gb": { "type": "number" },
|
||||||
|
"energy_wh": { "type": "number" },
|
||||||
|
"time_seconds": { "type": "number" }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"data_policy": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"policy_id": { "type": "string" },
|
||||||
|
"allowed_data": { "type": "array", "items": { "type": "string" } },
|
||||||
|
"constraints": { "type": "object" }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"scenarios": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "object",
|
||||||
|
"required": ["scenario_id"],
|
||||||
|
"properties": {
|
||||||
|
"scenario_id": { "type": "string" },
|
||||||
|
"sensors": { "type": "object" },
|
||||||
|
"environment": { "type": "object" },
|
||||||
|
"deterministic_replay": { "type": "boolean" },
|
||||||
|
"seed": { "type": ["integer", "null"] },
|
||||||
|
"description": { "type": "string" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"additionalProperties": false
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,34 @@
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
# jsonschema is an optional dependency used for schema validation tests.
|
||||||
|
# Skip these tests if jsonschema is not installed in the current test environment.
|
||||||
|
jsonschema = pytest.importorskip("jsonschema", reason="jsonschema not available; skipping schema validation tests")
|
||||||
|
from jsonschema import validate, ValidationError
|
||||||
|
|
||||||
|
|
||||||
|
def load_json(path: str):
|
||||||
|
with open(path, "r", encoding="utf-8") as f:
|
||||||
|
return json.load(f)
|
||||||
|
|
||||||
|
|
||||||
|
def test_example_contract_validates_against_schema():
|
||||||
|
schema = load_json(os.path.join(os.path.dirname(__file__), "..", "schemas", "safety_contract_schema.json"))
|
||||||
|
example = load_json(os.path.join(os.path.dirname(__file__), "..", "examples", "contracts", "example_contract.json"))
|
||||||
|
|
||||||
|
# Should not raise
|
||||||
|
validate(instance=example, schema=schema)
|
||||||
|
|
||||||
|
|
||||||
|
def test_schema_rejects_additional_properties():
|
||||||
|
schema = load_json(os.path.join(os.path.dirname(__file__), "..", "schemas", "safety_contract_schema.json"))
|
||||||
|
example = load_json(os.path.join(os.path.dirname(__file__), "..", "examples", "contracts", "example_contract.json"))
|
||||||
|
|
||||||
|
# Inject an unexpected property at top-level which is forbidden by additionalProperties=false
|
||||||
|
example_with_extra = dict(example)
|
||||||
|
example_with_extra["unexpected"] = "value"
|
||||||
|
|
||||||
|
with pytest.raises(ValidationError):
|
||||||
|
validate(instance=example_with_extra, schema=schema)
|
||||||
Loading…
Reference in New Issue