{"$schema":"https://json-schema.org/draft/2020-12/schema","$id":"runsave.declared-graph.v1","type":"object","additionalProperties":false,"required":["name","version","context","modules","connections"],"properties":{"name":{"type":"string","minLength":1,"maxLength":120},"version":{"type":"string","minLength":1,"maxLength":40},"context":{"enum":["distributed","server","client"]},"modules":{"type":"array","minItems":2,"maxItems":100,"uniqueItems":true,"items":{"type":"string","minLength":1,"maxLength":80}},"connections":{"type":"array","minItems":1,"maxItems":500,"items":{"type":"object","additionalProperties":false,"required":["from","to","type"],"properties":{"from":{"type":"string","minLength":1,"maxLength":80},"to":{"type":"string","minLength":1,"maxLength":80},"type":{"enum":["control","execution","state","signal","analysis","governance"]},"label":{"type":"string","maxLength":160}}}}},"description":"Declared graph only. Strings are trimmed by the engine. Endpoints must name declared modules; duplicate edges (from/to/type) are rejected. HTTP profile rejects empty labels, invalid Unicode and JSON nesting above 12."}