Interop Schema Reference¶
qortex uses JSON Schema to define the contract for consumer integration. Any system in any language can validate against these schemas.
Schema Versions¶
| Schema | Version | Description |
|---|---|---|
| Seed | 1.0 | Universal rule set format |
| Event | 1.0 | Signal log event format |
Seed Schema¶
The seed schema defines the universal rule set format used for all projections.
Full Schema¶
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://qortex.dev/schemas/seed.v1.schema.json",
"title": "Qortex Seed",
"description": "Universal rule set format for agent consumption",
"type": "object",
"required": ["persona", "version", "rules", "metadata"],
"properties": {
"persona": {
"type": "string",
"description": "Flat string identifier",
"minLength": 1
},
"version": {
"type": "integer",
"description": "Schema version as integer",
"minimum": 1
},
"rules": {
"type": "array",
"items": { "$ref": "#/$defs/rule" }
},
"metadata": { "$ref": "#/$defs/metadata" }
}
}
Example Seed¶
persona: error_handling_rules
version: 1
rules:
- rule: "Always configure timeouts for external calls"
category: error_handling
context: "When making HTTP requests or database queries"
antipattern: "Calling external services without timeout limits"
rationale: "Prevents cascading failures and resource exhaustion"
tags:
- timeout
- resilience
- error_handling
provenance:
id: rule:timeout
domain: error_handling
derivation: explicit
confidence: 1.0
relevance: 0.0
source_concepts:
- timeout
- circuit_breaker
relation_type: null
template_id: null
template_variant: null
template_severity: null
graph_version: "2026-02-05T12:00:00Z"
- rule: "Circuit Breaker requires Timeout to function correctly"
category: dependency
context: "When implementing the Circuit Breaker pattern"
antipattern: "Using Circuit Breaker without timeout configuration"
rationale: "Circuit Breaker needs timeout to detect failures"
tags:
- circuit_breaker
- timeout
- derived
provenance:
id: derived:circuit_breaker->timeout:imperative
domain: error_handling
derivation: derived
confidence: 0.95
relevance: 0.0
source_concepts:
- circuit_breaker
- timeout
relation_type: requires
template_id: requires:imperative
template_variant: imperative
template_severity: null
graph_version: "2026-02-05T12:00:00Z"
metadata:
source: qortex
source_version: "0.1.0"
projected_at: "2026-02-05T12:00:00Z"
rule_count: 2
Rule Object¶
| Field | Type | Required | Description |
|---|---|---|---|
rule |
string | Yes | The rule text itself |
category |
string | Yes | Category for filtering |
context |
string | No | When this rule applies |
antipattern |
string | No | What violating looks like |
rationale |
string | No | Why this matters |
tags |
array[string] | No | Searchable keywords |
provenance |
object | Yes | Origin and derivation metadata |
Provenance Object¶
| Field | Type | Required | Description |
|---|---|---|---|
id |
string | Yes | Unique rule identifier |
domain |
string | Yes | Knowledge domain |
derivation |
enum | Yes | "explicit" or "derived" |
confidence |
number | Yes | Confidence score (0-1) |
relevance |
number | No | Retrieval relevance score |
source_concepts |
array[string] | No | Concept IDs this derives from |
relation_type |
string|null | No | Edge type (for derived rules) |
template_id |
string|null | No | Template ID used |
template_variant |
string|null | No | Template variant |
template_severity |
string|null | No | Template severity |
graph_version |
string|null | No | Graph state timestamp |
Metadata Object¶
| Field | Type | Required | Description |
|---|---|---|---|
source |
string | Yes | Origin system ("qortex") |
source_version |
string | No | System version |
projected_at |
string | No | ISO timestamp of projection |
rule_count |
integer | Yes | Number of rules |
Event Schema¶
The event schema defines signal log entries.
Full Schema¶
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://qortex.dev/schemas/event.v1.schema.json",
"title": "Qortex Interop Event",
"description": "Signal log event for the consumer interop protocol",
"type": "object",
"required": ["event", "ts", "source"],
"properties": {
"event": {
"type": "string",
"enum": ["projection_complete", "seed_ingested", "seed_failed"]
},
"persona": { "type": "string" },
"domain": { "type": "string" },
"path": { "type": "string" },
"rule_count": { "type": "integer", "minimum": 0 },
"ts": { "type": "string", "format": "date-time" },
"source": { "type": "string" },
"source_version": { "type": "string" },
"error": { "type": "string" }
},
"additionalProperties": true
}
Event Types¶
| Event | Emitter | Description |
|---|---|---|
projection_complete |
qortex | New seed written to pending |
seed_ingested |
consumer | Seed successfully processed |
seed_failed |
consumer | Seed validation/processing failed |
Example Events¶
{"event":"projection_complete","persona":"error_rules","domain":"error_handling","path":"/home/user/.qortex/seeds/pending/error_rules_2026-02-05T12-00-00.yaml","rule_count":5,"ts":"2026-02-05T12:00:00Z","source":"qortex","source_version":"0.1.0"}
{"event":"seed_ingested","persona":"error_rules","path":"/home/user/.qortex/seeds/processed/error_rules_2026-02-05T12-00-00.yaml","ts":"2026-02-05T12:01:00Z","source":"buildlog","source_version":"1.2.0"}
{"event":"seed_failed","persona":"bad_seed","path":"/home/user/.qortex/seeds/failed/bad_seed.yaml","ts":"2026-02-05T12:02:00Z","source":"buildlog","error":"Missing required field: rules"}
Exporting Schemas¶
Export schema files for any-language validation:
qortex interop schema --output ./schemas/
Creates:
- schemas/seed.v1.schema.json
- schemas/event.v1.schema.json
Or programmatically:
from qortex.interop_schemas import export_schemas
seed_path, event_path = export_schemas("./schemas/")
Validation¶
Python¶
from qortex.interop_schemas import validate_seed, validate_event
# Validate a seed
errors = validate_seed(seed_dict)
if errors:
print(f"Invalid: {errors}")
# Validate an event
errors = validate_event(event_dict)
With full JSON Schema validation (requires jsonschema package):
import jsonschema
from qortex.interop_schemas import SEED_SCHEMA
validator = jsonschema.Draft202012Validator(SEED_SCHEMA)
errors = list(validator.iter_errors(seed_dict))
JavaScript/TypeScript¶
const Ajv = require("ajv");
const addFormats = require("ajv-formats");
const ajv = new Ajv();
addFormats(ajv);
const schema = require("./seed.v1.schema.json");
const validate = ajv.compile(schema);
if (!validate(seed)) {
console.log(validate.errors);
}
Go¶
import "github.com/xeipuuv/gojsonschema"
schemaLoader := gojsonschema.NewReferenceLoader("file:///path/to/seed.v1.schema.json")
documentLoader := gojsonschema.NewGoLoader(seed)
result, _ := gojsonschema.Validate(schemaLoader, documentLoader)
if !result.Valid() {
for _, err := range result.Errors() {
fmt.Println(err)
}
}
CLI¶
qortex interop validate seed.yaml
Schema Evolution¶
Schemas are versioned independently of qortex:
- Patch: Bug fixes, clarifications (no version bump)
- Minor: Additive changes, new optional fields (1.0 -> 1.1)
- Major: Breaking changes (1.x -> 2.0)
Consumers should:
1. Check version field in seeds
2. Reject seeds with major version mismatch
3. Accept seeds with higher minor versions (forward compatible)
Key Design Decisions¶
persona is flat string¶
# Correct
persona: error_handling_rules
# Wrong (old format)
persona:
name: error_handling_rules
description: ...
Consumers use persona as filename, so flat string is simpler.
version is integer¶
# Correct
version: 1
# Wrong
version: "1.0.0"
Integer comparison is simpler than semver parsing.
rule not text¶
# Correct
rules:
- rule: "Always configure timeouts"
# Wrong (old format)
rules:
- text: "Always configure timeouts"
More explicit and consistent with field naming.
provenance groups metadata¶
# Correct
rules:
- rule: "..."
provenance:
id: rule:timeout
domain: error_handling
# Wrong (old format)
rules:
- rule: "..."
id: rule:timeout
domain: error_handling
Grouping makes it clear what's informational vs operational.
Security Notes¶
Schemas validate structure, not content. Consumers must:
- Sanitize rule text before using in prompts
- Don't execute anything from seed files
- Validate paths from events before file operations
- Don't trust provenance for authorization decisions