{
  "schema_version": 2,
  "dialect": "KGLite Cypher",
  "claim": "An independently implemented Cypher dialect with a tested openCypher-compatible subset and documented extensions; not a complete openCypher or Neo4j implementation.",
  "status_definitions": {
    "covered": "Implemented behavior is locked by KGLite-authored contract tests.",
    "partial": "Useful behavior exists, but a documented semantic or syntactic gap remains.",
    "extension": "KGLite behavior outside the claimed openCypher-compatible subset.",
    "unsupported": "Rejected or deliberately not implemented.",
    "intentional_divergence": "Supported behavior deliberately differs for KGLite's data model or runtime."
  },
  "case_ids_definition": "Every covered or partial feature lists the tests/cypher_contract/cases.json case IDs that execute its claimed behavior; the contract test rejects claims with no executable case.",
  "coverage_gaps": [],
  "features": [
    {"id": "clause.match", "syntax": "MATCH", "status": "partial", "case_ids": ["match.undirected", "match.variable_length", "create.relationship", "match.abbreviated_outgoing", "match.abbreviated_incoming", "match.abbreviated_undirected"], "note": "Core node, relationship, variable-length, shortest-path, abbreviated (-->, --, <--), and relationship-unique trail patterns are covered; not every openCypher pattern grammar form is implemented."},
    {"id": "clause.optional_match", "syntax": "OPTIONAL MATCH", "status": "covered", "case_ids": ["match.optional_missing"], "note": "Null-extending optional pattern matches."},
    {"id": "clause.where", "syntax": "WHERE", "status": "covered", "case_ids": ["where.three_valued_filter", "exists.cross_pattern_uniqueness"], "note": "Predicates preserve three-valued boolean, membership, and quantifier semantics; EXISTS subqueries enforce relationship uniqueness across their comma patterns."},
    {"id": "clause.return", "syntax": "RETURN", "status": "covered", "case_ids": ["return.distinct", "merge.idempotent", "scalar.integer_addition"], "note": "Projection, aliases, DISTINCT, and aggregation."},
    {"id": "clause.with", "syntax": "WITH", "status": "covered", "case_ids": ["with.aggregation"], "note": "Projection, aggregation, wildcard preservation, and strict post-projection scope validation."},
    {"id": "clause.order", "syntax": "ORDER BY / SKIP / LIMIT", "status": "covered", "case_ids": ["unwind.order", "order.skip_limit"], "note": "Stable multi-key ordering and pagination."},
    {"id": "clause.unwind", "syntax": "UNWIND", "status": "covered", "case_ids": ["unwind.order", "unwind.empty_list", "unwind.null"], "note": "List expansion including null and empty-list behavior."},
    {"id": "clause.union", "syntax": "UNION / UNION ALL", "status": "covered", "case_ids": ["union.distinct", "union.all_duplicates"], "note": "Duplicate-removing and duplicate-preserving set composition."},
    {"id": "clause.create", "syntax": "CREATE", "status": "covered", "case_ids": ["create.node", "create.relationship"], "note": "Node and relationship creation with inline properties."},
    {"id": "clause.set", "syntax": "SET", "status": "covered", "case_ids": ["set.property"], "note": "Property, label, map merge, and mutable-property map replacement forms."},
    {"id": "clause.delete", "syntax": "DELETE / DETACH DELETE / REMOVE", "status": "covered", "case_ids": ["delete.node", "delete.detach", "remove.property"], "note": "Entity deletion, detach deletion, and property/label removal."},
    {"id": "clause.merge", "syntax": "MERGE", "status": "covered", "case_ids": ["merge.idempotent"], "note": "Pattern merge and ON CREATE/ON MATCH reject null property keys before mutation."},
    {"id": "clause.foreach", "syntax": "FOREACH", "status": "covered", "case_ids": ["foreach.update"], "note": "Updating bodies and nested FOREACH are supported."},
    {"id": "clause.call_subquery", "syntax": "CALL { ... }", "status": "partial", "case_ids": ["call.subquery_correlated"], "note": "Read subqueries support correlated importing WITH; unit, write, UNION-body, and IN TRANSACTIONS forms are not supported."},
    {"id": "clause.load_csv", "syntax": "LOAD CSV", "status": "unsupported", "note": "Use the Python, Rust, or blueprint ingestion APIs."},
    {"id": "expression.boolean", "syntax": "AND / OR / XOR / NOT", "status": "covered", "case_ids": ["boolean.three_valued"], "note": "Expression and predicate positions preserve three-valued results with standard precedence."},
    {"id": "expression.in", "syntax": "IN", "status": "covered", "case_ids": ["in.null_membership"], "note": "Membership preserves unknown for null operands and null-containing no-match lists."},
    {"id": "expression.list", "syntax": "list literals, indexing, slicing, concatenation", "status": "covered", "case_ids": ["list.literal", "list.index", "list.slice", "list.concatenation"], "note": "List composition supports list/list and element/list forms; indexes and slice bounds require integers."},
    {"id": "expression.quantifiers", "syntax": "any / all / none / single", "status": "covered", "case_ids": ["quantifier.any", "quantifier.decisive"], "note": "Quantifiers preserve unknown unless a decisive true/false result exists."},
    {"id": "expression.case", "syntax": "CASE", "status": "covered", "case_ids": ["case.generic", "case.simple", "case.predicate_result"], "note": "Simple and generic CASE forms; operand, WHEN, THEN, and ELSE positions accept full expressions including comparisons and pattern predicates."},
    {"id": "expression.count_subquery", "syntax": "COUNT { ... }", "status": "covered", "case_ids": ["count_subquery.cross_pattern_uniqueness", "count_subquery.join_rows"], "note": "COUNT subqueries count the subquery's result rows: comma patterns within one clause group join on shared variables under relationship uniqueness (the trail rule), and separate MATCH clauses inside the subquery are independent clause scopes whose rows join/multiply, as at the top level."},
    {"id": "expression.reserved_word_names", "syntax": "soft keywords as names", "status": "covered", "case_ids": ["names.soft_keyword_verbatim_case"], "note": "Operator/sort/mutation keywords (CONTAINS, ORDER, IN, MERGE, ...) are accepted as labels, relationship types, property keys, map keys, and aliases, and keep their verbatim source spelling (0.12.14 and earlier canonicalized them to uppercase, so a graph written by an older release may store ORDER where a lowercase source now reads order). Clause-flow and value keywords stay reserved; backticks escape any name."},
    {"id": "path.values", "syntax": "nodes(p) / relationships(p)", "status": "covered", "case_ids": ["path.decomposition", "path.node_order"], "note": "Path values preserve exact node order, relationship identity, properties, and traversal direction, including parallel and incoming edges."},
    {"id": "function.id", "syntax": "id(entity)", "status": "covered", "case_ids": ["function.id_identity"], "note": "Returns KGLite logical node identity or stable relationship identity."},
    {"id": "pattern.var_length_default_cap", "syntax": "-[*]-> / -[*N..]->", "status": "intentional_divergence", "case_ids": ["match.var_length_default_cap", "match.var_length_min_above_default_cap"], "note": "Open-ended variable-length patterns default to a 10-hop ceiling as a runaway-query guard (openCypher's * is unbounded). An explicit minimum above the ceiling raises it to that minimum so the range is never silently empty, and a range whose minimum exceeds its maximum is rejected at parse time."},
    {"id": "model.labels", "syntax": "labels(n) / SET n:Label", "status": "intentional_divergence", "note": "KGLite stores one immutable primary type plus additive secondary labels; labels(n) returns primary type first."},
    {"id": "transaction.model", "syntax": "transactions", "status": "intentional_divergence", "note": "Embedded snapshots and optimistic commit checking replace a remote database transaction service."}
  ],
  "extensions": [
    {"id": "extension.namespace", "kind": "naming", "canonical": "kglite.*", "legacy": "flat names", "note": "KGLite functions and procedures accept canonical namespaced spellings; historical flat spellings remain equivalent."},
    {"id": "extension.analytics", "kind": "procedure_family", "canonical": "kglite.pagerank and related procedures", "legacy": "pagerank and related flat names", "note": "Graph algorithms, rules, code analysis, and statistics procedures."},
    {"id": "extension.semantic", "kind": "function_family", "canonical": "kglite.text_score / kglite.vector_score", "legacy": "text_score / vector_score", "note": "Embedding-backed semantic scoring."},
    {"id": "extension.spatial", "kind": "function_family", "canonical": "kglite.geom_* and KGLite spatial helpers", "legacy": "flat function names", "note": "Pragmatic geometry and spatial helpers beyond the compatible subset."},
    {"id": "extension.timeseries", "kind": "function_family", "canonical": "kglite.ts_*", "legacy": "ts_*", "note": "Time-series channel functions."},
    {"id": "extension.text", "kind": "function_family", "canonical": "kglite.text_*", "legacy": "text_*", "note": "Text normalization, matching, token, and distance helpers."},
    {"id": "extension.having", "kind": "clause", "canonical": "HAVING", "legacy": null, "note": "Post-aggregation filter accepted as a KGLite extension."},
    {"id": "extension.window", "kind": "expression", "canonical": "OVER", "legacy": null, "note": "Window functions are a KGLite/GQL-style extension."},
    {"id": "extension.set_operators", "kind": "clause", "canonical": "INTERSECT / EXCEPT", "legacy": null, "note": "Additional set operators outside the claimed openCypher-compatible subset."},
    {"id": "extension.explain_profile", "kind": "clause", "canonical": "EXPLAIN / PROFILE", "legacy": null, "note": "KGLite plan and execution diagnostics; output shape is KGLite-specific."}
  ]
}
