causlModelJsonSchema: {
    $id: "https://causl.dev/schemas/causl-model-v3.json";
    $schema: "http://json-schema.org/draft-07/schema#";
    additionalProperties: false;
    properties: {
        bridges: {
            items: {
                additionalProperties: false;
                properties: {
                    dep: { minLength: 1; type: "string" };
                    from: { minLength: 1; type: "string" };
                    policy: { enum: readonly ["legacy-allow", "test-only", "read-only"] };
                    to: { minLength: 1; type: "string" };
                };
                required: readonly ["from", "to", "dep", "policy"];
                type: "object";
            };
            type: "array";
        };
        commits: {
            items: {
                additionalProperties: false;
                properties: {
                    callGraph: {
                        additionalProperties: false;
                        properties: {
                            frames: { type: "array" };
                            truncatedDeeper: { type: "boolean" };
                        };
                        required: readonly ["frames", "truncatedDeeper"];
                        type: "object";
                    };
                    changedNodes: { items: { type: "string" }; type: "array" };
                    graphId: { minLength: 1; type: "string" };
                    intent: { type: "string" };
                    originatedAt: { minimum: 0; type: "integer" };
                    originEvent: { type: "string" };
                    time: { minimum: 0; type: "integer" };
                };
                required: readonly ["time", "graphId", "intent", "changedNodes"];
                type: "object";
            };
            type: "array";
        };
        events: {
            items: {
                oneOf: readonly [
                    {
                        additionalProperties: false;
                        properties: {
                            callbackSite: { type: "string" };
                            graphId: { minLength: 1; type: "string" };
                            id: { minLength: 1; type: "string" };
                            kind: { const: "subscribe" };
                            scopeId: { minLength: 1; type: "string" };
                            target: { minLength: 1; type: "string" };
                            time: { minimum: 0; type: "integer" };
                        };
                        required: readonly [
                            "kind",
                            "graphId",
                            "id",
                            "scopeId",
                            "target",
                            "callbackSite",
                            "time",
                        ];
                        type: "object";
                    },
                    {
                        additionalProperties: false;
                        properties: {
                            firedAt: { minimum: 0; type: "integer" };
                            graphId: { minLength: 1; type: "string" };
                            id: { minLength: 1; type: "string" };
                            kind: { const: "subscribe-callback" };
                            subscribeId: { minLength: 1; type: "string" };
                        };
                        required: readonly ["kind", "graphId", "id", "subscribeId", "firedAt"];
                        type: "object";
                    },
                    {
                        additionalProperties: false;
                        properties: {
                            graphId: { minLength: 1; type: "string" };
                            id: { minLength: 1; type: "string" };
                            kind: { const: "unsubscribe" };
                            scopeId: { minLength: 1; type: "string" };
                            time: { minimum: 0; type: "integer" };
                        };
                        required: readonly ["kind", "graphId", "id", "scopeId", "time"];
                        type: "object";
                    },
                    {
                        additionalProperties: false;
                        properties: {
                            disposeAt: {
                                items: { minimum: 0; type: "integer" };
                                type: "array";
                            };
                            graphId: { minLength: 1; type: "string" };
                            kind: { const: "dispose" };
                            nodeId: { minLength: 1; type: "string" };
                            scopeId: { minLength: 1; type: "string" };
                            time: { minimum: 0; type: "integer" };
                        };
                        required: readonly [
                            "kind",
                            "graphId",
                            "nodeId",
                            "scopeId",
                            "time",
                            "disposeAt",
                        ];
                        type: "object";
                    },
                    {
                        additionalProperties: false;
                        properties: {
                            derivedId: { minLength: 1; type: "string" };
                            graphId: { minLength: 1; type: "string" };
                            kind: { const: "read" };
                            readNodeId: { minLength: 1; type: "string" };
                            seq: { minimum: 0; type: "integer" };
                            time: { minimum: 0; type: "integer" };
                            truncated: { type: "boolean" };
                        };
                        required: readonly [
                            "kind",
                            "graphId",
                            "derivedId",
                            "readNodeId",
                            "time",
                            "seq",
                            "truncated",
                        ];
                        type: "object";
                    },
                    {
                        additionalProperties: false;
                        properties: {
                            graphId: { minLength: 1; type: "string" };
                            inputId: { minLength: 1; type: "string" };
                            kind: { const: "tx-set" };
                            time: { minimum: 0; type: "integer" };
                        };
                        required: readonly ["kind", "graphId", "inputId", "time"];
                        type: "object";
                    },
                ];
            };
            type: "array";
        };
        nodes: {
            items: {
                oneOf: readonly [
                    {
                        additionalProperties: false;
                        properties: {
                            graphId: { minLength: 1; type: "string" };
                            id: { minLength: 1; type: "string" };
                            kind: { const: "input" };
                            serializable: { type: "boolean" };
                            value: {};
                        };
                        required: readonly ["kind", "id", "graphId", "value", "serializable"];
                        type: "object";
                    },
                    {
                        additionalProperties: false;
                        properties: {
                            conditionalDeps: { items: { type: "string" }; type: "array" };
                            deps: { items: { type: "string" }; type: "array" };
                            graphId: { minLength: 1; type: "string" };
                            id: { minLength: 1; type: "string" };
                            kind: { const: "derived" };
                            serializable: { type: "boolean" };
                            value: {};
                        };
                        required: readonly [
                            "kind",
                            "id",
                            "graphId",
                            "deps",
                            "conditionalDeps",
                            "value",
                            "serializable",
                        ];
                        type: "object";
                    },
                ];
            };
            type: "array";
        };
        schema: { const: 3 };
        scopes: {
            items: {
                additionalProperties: false;
                properties: {
                    id: { minLength: 1; type: "string" };
                    kind: { enum: readonly ["ephemeral", "infinite", "process-exit"] };
                    lifetime: {
                        additionalProperties: false;
                        properties: {
                            origin: { type: "string" };
                            terminator: { type: "string" };
                        };
                        required: readonly ["origin", "terminator"];
                        type: "object";
                    };
                };
                required: readonly ["id", "kind", "lifetime"];
                type: "object";
            };
            type: "array";
        };
        time: { minimum: 0; type: "integer" };
    };
    required: readonly [
        "schema",
        "time",
        "nodes",
        "commits",
        "events",
        "scopes",
        "bridges",
    ];
    title: "CauslModel";
    type: "object";
} = ...

Draft-07 JSON Schema document for the CauslModel IR.

Type declaration

  • Readonly$id: "https://causl.dev/schemas/causl-model-v3.json"
  • Readonly$schema: "http://json-schema.org/draft-07/schema#"
  • ReadonlyadditionalProperties: false
  • Readonlyproperties: {
        bridges: {
            items: {
                additionalProperties: false;
                properties: {
                    dep: { minLength: 1; type: "string" };
                    from: { minLength: 1; type: "string" };
                    policy: { enum: readonly ["legacy-allow", "test-only", "read-only"] };
                    to: { minLength: 1; type: "string" };
                };
                required: readonly ["from", "to", "dep", "policy"];
                type: "object";
            };
            type: "array";
        };
        commits: {
            items: {
                additionalProperties: false;
                properties: {
                    callGraph: {
                        additionalProperties: false;
                        properties: {
                            frames: { type: "array" };
                            truncatedDeeper: { type: "boolean" };
                        };
                        required: readonly ["frames", "truncatedDeeper"];
                        type: "object";
                    };
                    changedNodes: { items: { type: "string" }; type: "array" };
                    graphId: { minLength: 1; type: "string" };
                    intent: { type: "string" };
                    originatedAt: { minimum: 0; type: "integer" };
                    originEvent: { type: "string" };
                    time: { minimum: 0; type: "integer" };
                };
                required: readonly ["time", "graphId", "intent", "changedNodes"];
                type: "object";
            };
            type: "array";
        };
        events: {
            items: {
                oneOf: readonly [
                    {
                        additionalProperties: false;
                        properties: {
                            callbackSite: { type: "string" };
                            graphId: { minLength: 1; type: "string" };
                            id: { minLength: 1; type: "string" };
                            kind: { const: "subscribe" };
                            scopeId: { minLength: 1; type: "string" };
                            target: { minLength: 1; type: "string" };
                            time: { minimum: 0; type: "integer" };
                        };
                        required: readonly [
                            "kind",
                            "graphId",
                            "id",
                            "scopeId",
                            "target",
                            "callbackSite",
                            "time",
                        ];
                        type: "object";
                    },
                    {
                        additionalProperties: false;
                        properties: {
                            firedAt: { minimum: 0; type: "integer" };
                            graphId: { minLength: 1; type: "string" };
                            id: { minLength: 1; type: "string" };
                            kind: { const: "subscribe-callback" };
                            subscribeId: { minLength: 1; type: "string" };
                        };
                        required: readonly ["kind", "graphId", "id", "subscribeId", "firedAt"];
                        type: "object";
                    },
                    {
                        additionalProperties: false;
                        properties: {
                            graphId: { minLength: 1; type: "string" };
                            id: { minLength: 1; type: "string" };
                            kind: { const: "unsubscribe" };
                            scopeId: { minLength: 1; type: "string" };
                            time: { minimum: 0; type: "integer" };
                        };
                        required: readonly ["kind", "graphId", "id", "scopeId", "time"];
                        type: "object";
                    },
                    {
                        additionalProperties: false;
                        properties: {
                            disposeAt: {
                                items: { minimum: 0; type: "integer" };
                                type: "array";
                            };
                            graphId: { minLength: 1; type: "string" };
                            kind: { const: "dispose" };
                            nodeId: { minLength: 1; type: "string" };
                            scopeId: { minLength: 1; type: "string" };
                            time: { minimum: 0; type: "integer" };
                        };
                        required: readonly [
                            "kind",
                            "graphId",
                            "nodeId",
                            "scopeId",
                            "time",
                            "disposeAt",
                        ];
                        type: "object";
                    },
                    {
                        additionalProperties: false;
                        properties: {
                            derivedId: { minLength: 1; type: "string" };
                            graphId: { minLength: 1; type: "string" };
                            kind: { const: "read" };
                            readNodeId: { minLength: 1; type: "string" };
                            seq: { minimum: 0; type: "integer" };
                            time: { minimum: 0; type: "integer" };
                            truncated: { type: "boolean" };
                        };
                        required: readonly [
                            "kind",
                            "graphId",
                            "derivedId",
                            "readNodeId",
                            "time",
                            "seq",
                            "truncated",
                        ];
                        type: "object";
                    },
                    {
                        additionalProperties: false;
                        properties: {
                            graphId: { minLength: 1; type: "string" };
                            inputId: { minLength: 1; type: "string" };
                            kind: { const: "tx-set" };
                            time: { minimum: 0; type: "integer" };
                        };
                        required: readonly ["kind", "graphId", "inputId", "time"];
                        type: "object";
                    },
                ];
            };
            type: "array";
        };
        nodes: {
            items: {
                oneOf: readonly [
                    {
                        additionalProperties: false;
                        properties: {
                            graphId: { minLength: 1; type: "string" };
                            id: { minLength: 1; type: "string" };
                            kind: { const: "input" };
                            serializable: { type: "boolean" };
                            value: {};
                        };
                        required: readonly ["kind", "id", "graphId", "value", "serializable"];
                        type: "object";
                    },
                    {
                        additionalProperties: false;
                        properties: {
                            conditionalDeps: { items: { type: "string" }; type: "array" };
                            deps: { items: { type: "string" }; type: "array" };
                            graphId: { minLength: 1; type: "string" };
                            id: { minLength: 1; type: "string" };
                            kind: { const: "derived" };
                            serializable: { type: "boolean" };
                            value: {};
                        };
                        required: readonly [
                            "kind",
                            "id",
                            "graphId",
                            "deps",
                            "conditionalDeps",
                            "value",
                            "serializable",
                        ];
                        type: "object";
                    },
                ];
            };
            type: "array";
        };
        schema: { const: 3 };
        scopes: {
            items: {
                additionalProperties: false;
                properties: {
                    id: { minLength: 1; type: "string" };
                    kind: { enum: readonly ["ephemeral", "infinite", "process-exit"] };
                    lifetime: {
                        additionalProperties: false;
                        properties: {
                            origin: { type: "string" };
                            terminator: { type: "string" };
                        };
                        required: readonly ["origin", "terminator"];
                        type: "object";
                    };
                };
                required: readonly ["id", "kind", "lifetime"];
                type: "object";
            };
            type: "array";
        };
        time: { minimum: 0; type: "integer" };
    }
  • Readonlyrequired: readonly ["schema", "time", "nodes", "commits", "events", "scopes", "bridges"]
  • Readonlytitle: "CauslModel"
  • Readonlytype: "object"

The schema is as const so consumers can derive a precise literal type (CauslModelJsonSchema) for compile-time validation tooling. Validation libraries (Ajv, etc.) accept the value directly at runtime.

Schema 3 (PR-B1). Every node and commit carries graphId (the multi-graph foreign key); the top-level document also carries the events lifecycle stream, the scopes registry resolved by IRSubscribe.scopeId, and the bridges allowlist consumed by EPIC-2's CrossGraphRead pass. Each event variant is closed under oneOf over its kind discriminator — subscribe, subscribe-callback, unsubscribe, dispose, read, tx-set.