(* Numeric lexical forms are validated under Core §9.3: finite binary64,
safe integral values in every spelling, and no nonzero underflow. *)
(* ========================================================================= *)
(* KIP 2.0 KML Formal EBNF *)
(* ========================================================================= *)
(* Status: Formal syntax draft aligned to KIP-2.0-SPECIFICATION.md 2.0-draft.
Language: KML — Cognitive Mutation Language.
This grammar defines syntax only. Runtime validation still decides:
- Schema symbol resolution and field mutability;
- stable identity legality for UPSERT;
- whether a local handle is unique/bound;
- whether forward references resolve;
- ActorBinding/Governance authority;
- lifecycle compatibility;
- whether a target is immutable, terminal, held, referenced, etc.;
- transaction preconditions and serializability.
Formalization decisions made here:
1. Keywords are ASCII case-insensitive; canonical rendering is uppercase.
2. CREATE CONCEPT/EVIDENCE/ASSERTION/ACTIVITY requires a local handle.
ENSURE PROPOSITION and the ASSERT sugar keep optional handles.
3. MUTATE contains mutation clauses but cannot recursively contain MUTATE.
4. KML WHERE uses raw KQL-visible-state patterns. BELIEF/BELIEF SLOT are
intentionally excluded from this mutation grammar; a virtual Projection
can never be a mutation target.
5. TRANSITION is the single lifecycle statement: the quoted state names
the move (retracted | superseded | corrected | running | completed |
failed | cancelled | archived | tombstoned), BY names the successor
for superseded / corrected, and SET FIELDS / SET STRUCTURAL finalize
a terminal Activity atomically. Which states fit which target kind
and which current state is a runtime check (InvalidLifecycleTransition),
so there is no EXPECT STATE guard.
5a. EXPECT VERSION is always the trailing clause of a mutation — after
WHERE and LIMIT, after UPSERT's closing brace, after ENSURE
PROPOSITION's tuple — and may repeat, one guard per version plane
(OF ATTRIBUTES | STRUCTURAL | RETENTION | FACET "X"). Repeating a
plane is a semantic error, not a grammatical one.
6. PURGE freezes the explicit confirmation spelling as CONFIRM "PURGE".
PURGE PAYLOAD reuses it; it takes no REFERENCE POLICY clause because
the Evidence element survives a payload purge (Spec §60.6).
6a. Every mutation whose WHERE can select an unbounded set accepts an
optional LIMIT immediately after that WHERE (UPDATE, TRANSITION,
SET RETENTION, PURGE, PURGE PAYLOAD). MERGE CONCEPT does not:
its source and target are already named, and its WHERE only guards.
6b. Every statement that takes a `target_ref` treats WHERE the same way,
UPDATE included: a `?variable` target is bound by the WHERE block, a
`:parameter` / "id" target already names the element and MAY omit
WHERE (a WHERE given anyway only guards, as it does for MERGE).
Whether a bare `?variable` target is actually bound is a semantic
check, not a grammatical one — inside MUTATE it may be a local handle.
6c. Every SET has an UNSET. UNSET STRUCTURAL removes one Structural
Reference per entry, `( field, target )` — the SET STRUCTURAL entry
without its options object — and appears exactly where UNSET
ATTRIBUTES does (UPSERT CONCEPT, UPDATE). CREATE has nothing to
remove; record kinds keep their immutable topology (Spec §17.5).
7. Shared rule names must stay definitionally identical across the
KQL/KML/META grammars, except the two reviewed divergences owned by
KQL (`proposition_tuple` raw predicate paths, `where_clause` BELIEF
patterns); `../formal/grammar/check_ebnf.py` enforces this.
*)
(* ------------------------------------------------------------------------- *)
(* Lexical conventions *)
(* ------------------------------------------------------------------------- *)
(* Protocol keywords are ASCII case-insensitive. Canonical rendering uses
uppercase spelling. Schema symbols, identifiers inside strings, and string
values remain case-sensitive according to their own contracts.
Whitespace and line comments beginning with // are ignored between tokens.
This EBNF uses:
= definition
| alternative
[ ... ] optional
{ ... } zero-or-more repetition
( ... ) grouping
"..." terminal token
? ... ? lexical special sequence
*)
identifier = identifier_start, { identifier_continue } ;
identifier_start = ? ASCII letter or "_" ? ;
identifier_continue
= ? ASCII letter, ASCII digit or "_" ? ;
variable = "?", identifier ;
parameter = ":", identifier ;
number_literal = [ "-" ], integer_part, [ fraction_part ], [ exponent_part ] ;
integer_part = "0" | nonzero_digit, { digit } ;
fraction_part = ".", digit, { digit } ;
exponent_part = ( "e" | "E" ), [ "+" | "-" ], digit, { digit } ;
digit = "0" | "1" | "2" | "3" | "4"
| "5" | "6" | "7" | "8" | "9" ;
nonzero_digit = "1" | "2" | "3" | "4" | "5"
| "6" | "7" | "8" | "9" ;
string_literal = '"', { string_character }, '"' ;
string_character = unescaped_string_character | escape_sequence ;
unescaped_string_character
= ? Unicode scalar value except quotation mark, reverse solidus,
and U+0000 through U+001F ? ;
escape_sequence = "\", ( '"' | "\" | "/" | "b" | "f" | "n" | "r" | "t"
| unicode_escape ) ;
unicode_escape = "u", hex_digit, hex_digit, hex_digit, hex_digit ;
hex_digit = digit | "A" | "B" | "C" | "D" | "E" | "F"
| "a" | "b" | "c" | "d" | "e" | "f" ;
boolean_literal = "true" | "false" ;
null_literal = "null" ;
literal = string_literal | number_literal | boolean_literal | null_literal ;
schema_symbol = string_literal | parameter ;
field_name = identifier | string_literal ;
array_literal = "[", [ data_value, { ",", data_value } ], "]" ;
object_literal = "{", [ object_member, { ",", object_member } ], "}" ;
object_member = field_name, ":", data_value ;
data_value = parameter
| variable
| literal
| array_literal
| object_literal
| function_call
| field_access ;
field_access = variable, { field_step } ;
field_step = ".", identifier | "[", string_literal, "]" ;
function_call = identifier, "(", [ expression_list ], ")" ;
expression_list = expression, { ",", expression } ;
primary_expression
= field_access
| variable
| parameter
| literal
| array_literal
| object_literal
| function_call
| "(", expression, ")" ;
unary_expression = [ "!" | "-" ], primary_expression ;
relational_expression
= unary_expression,
[ ( "<" | ">" | "<=" | ">=" ), unary_expression ] ;
equality_expression
= relational_expression,
{ ( "==" | "!=" ), relational_expression } ;
and_expression = equality_expression, { "&&", equality_expression } ;
or_expression = and_expression, { "||", and_expression } ;
expression = or_expression ;
(* ------------------------------------------------------------------------- *)
(* Entry point *)
(* ------------------------------------------------------------------------- *)
kml = kml_statement ;
kml_statement = mutate_statement
| create_concept
| upsert_concept
| ensure_proposition
| assert_statement
| create_evidence
| create_assertion
| create_activity
| update_statement
| transition_statement
| set_retention
| purge_statement
| purge_payload_statement
| merge_concept ;
mutate_statement = "MUTATE", "{", { mutation_clause }, "}" ;
mutation_clause = create_concept
| upsert_concept
| ensure_proposition
| assert_statement
| create_evidence
| create_assertion
| create_activity
| update_statement
| transition_statement
| set_retention
| purge_statement
| purge_payload_statement
| merge_concept ;
(* Every mutation shares one tail: [WHERE] [LIMIT] { EXPECT VERSION }, with a
statement's own trailing words (REFERENCE POLICY, CONFIRM) after it
(Spec §52.8). *)
(* ------------------------------------------------------------------------- *)
(* Create / ensure / upsert *)
(* ------------------------------------------------------------------------- *)
create_concept = "CREATE", "CONCEPT", handle,
"{", { concept_create_clause }, "}" ;
concept_create_clause
= type_clause
| client_key_clause
| name_clause
| set_fields_clause
| set_attributes_clause
| set_facet_clause
| set_structural_clause ;
upsert_concept = "UPSERT", "CONCEPT", handle,
"{", { upsert_clause }, "}",
{ expect_version_clause } ;
upsert_clause = match_clause
| set_fields_clause
| set_attributes_clause
| set_facet_clause
| unset_attributes_clause
| unset_facet_clause
| set_structural_clause
| unset_structural_clause ;
ensure_proposition
= "ENSURE", "PROPOSITION", [ handle ],
proposition_tuple,
{ expect_version_clause } ;
(* Normative sugar (Spec §55.1): ensure Proposition + create Assertion,
with optional supersession (TRANSITION ... TO "superseded" BY the new
Assertion). Member keys (by, mode, stance, confidence, at, valid,
evidence, key) are validated semantically. *)
assert_statement = "ASSERT", [ handle ], proposition_tuple,
assignment_object,
[ "SUPERSEDING", target_ref ] ;
create_evidence = "CREATE", "EVIDENCE", handle,
"{", { record_create_clause }, "}" ;
create_assertion = "CREATE", "ASSERTION", handle,
"{", { record_create_clause }, "}" ;
create_activity = "CREATE", "ACTIVITY", handle,
"{", { record_create_clause }, "}" ;
record_create_clause
= client_key_clause
| set_fields_clause
| set_facet_clause
| set_structural_clause ;
type_clause = "TYPE", schema_symbol ;
client_key_clause
= "CLIENT", "KEY", scalar_or_parameter ;
name_clause = "NAME", scalar_or_parameter ;
match_clause = "MATCH", object_pattern ;
(* ------------------------------------------------------------------------- *)
(* Generic update *)
(* ------------------------------------------------------------------------- *)
update_statement = "UPDATE", target_ref,
update_action, { update_action },
[ "WHERE", where_block ],
[ limit_clause ],
{ expect_version_clause } ;
update_action = set_fields_clause
| set_attributes_clause
| set_facet_clause
| unset_attributes_clause
| unset_facet_clause
| set_structural_clause
| unset_structural_clause ;
set_fields_clause
= "SET", "FIELDS", assignment_object ;
set_attributes_clause
= "SET", "ATTRIBUTES", assignment_object ;
set_facet_clause = "SET", "FACET", schema_symbol, assignment_object ;
unset_attributes_clause
= "UNSET", "ATTRIBUTES", unset_field_set ;
unset_facet_clause
= "UNSET", "FACET", schema_symbol, unset_field_set ;
set_structural_clause
= "SET", "STRUCTURAL", "{",
{ structural_assignment }, "}" ;
structural_assignment
= "(", schema_symbol, ",", mutation_value, ")",
[ object_literal ] ;
unset_structural_clause
= "UNSET", "STRUCTURAL", "{",
{ structural_removal }, "}" ;
structural_removal
= "(", schema_symbol, ",", mutation_value, ")" ;
assignment_object
= "{", [ assignment_member, { ",", assignment_member } ], "}" ;
assignment_member
= field_name, ":", mutation_value ;
unset_field_set = "{",
[ unset_field, { ",", unset_field } ],
"}" ;
unset_field = identifier | string_literal ;
(* ------------------------------------------------------------------------- *)
(* Lifecycle — one statement (Spec §52.5) *)
(* ------------------------------------------------------------------------- *)
(* The state names the move; the engine validates it against the target's
kind and current state:
Assertion "retracted" | "superseded" BY new_assertion
Evidence "corrected" BY new_evidence
Activity "running" | "completed" | "failed" | "cancelled"
(a terminal move may finalize fields and topology)
any "archived" | "tombstoned"
A move from the wrong state fails InvalidLifecycleTransition, so there is
no EXPECT STATE; EXPECT VERSION guards concurrency. *)
transition_statement
= "TRANSITION", target_ref,
"TO", scalar_or_parameter,
[ "BY", target_ref ],
{ transition_finalize_clause },
[ "WHERE", where_block ],
[ limit_clause ],
{ expect_version_clause } ;
transition_finalize_clause
= set_fields_clause | set_structural_clause ;
(* ------------------------------------------------------------------------- *)
(* Retention / storage lifecycle *)
(* ------------------------------------------------------------------------- *)
set_retention = "SET", "RETENTION", target_ref,
assignment_object,
[ "WHERE", where_block ],
[ limit_clause ],
{ expect_version_clause } ;
purge_statement = "PURGE", target_ref,
[ "WHERE", where_block ],
[ limit_clause ],
{ expect_version_clause },
[ "REFERENCE", "POLICY", scalar_or_parameter ],
"CONFIRM", '"PURGE"' ;
purge_payload_statement
= "PURGE", "PAYLOAD", target_ref,
[ "WHERE", where_block ],
[ limit_clause ],
{ expect_version_clause },
"CONFIRM", '"PURGE"' ;
merge_concept = "MERGE", "CONCEPT", target_ref,
"INTO", target_ref,
[ "WHERE", where_block ],
{ expect_version_clause } ;
(* ------------------------------------------------------------------------- *)
(* Preconditions *)
(* ------------------------------------------------------------------------- *)
(* Without a plane the guard compares _system.version; with one, that
plane's own version (Spec §35.1). At most one guard per plane. *)
expect_version_clause
= "EXPECT", "VERSION", scalar_or_parameter,
[ "OF", version_plane ] ;
version_plane = "ATTRIBUTES"
| "STRUCTURAL"
| "RETENTION"
| "FACET", schema_symbol ;
limit_clause = "LIMIT", scalar_or_parameter ;
(* ------------------------------------------------------------------------- *)
(* Raw KQL matching subset used by KML WHERE *)
(* ------------------------------------------------------------------------- *)
where_block = "{", { where_clause }, "}" ;
where_clause = concept_pattern
| proposition_pattern
| assertion_pattern
| evidence_pattern
| activity_pattern
| structural_pattern
| filter_clause
| not_clause
| optional_clause
| union_clause ;
concept_pattern = variable, [ "CONCEPT" ], object_pattern ;
proposition_pattern
= [ variable ], [ "PROPOSITION" ], proposition_tuple ;
assertion_pattern
= variable, "ASSERTION", object_pattern ;
evidence_pattern = variable, "EVIDENCE", object_pattern ;
activity_pattern = variable, "ACTIVITY", object_pattern ;
structural_pattern
= [ variable ], "STRUCTURAL", "(",
term, ",", schema_symbol, ",", term, ")" ;
filter_clause = "FILTER", "(", expression, ")" ;
not_clause = "NOT", where_block ;
optional_clause = "OPTIONAL", where_block ;
union_clause = "UNION", where_block ;
(* ------------------------------------------------------------------------- *)
(* Terms / objects *)
(* ------------------------------------------------------------------------- *)
handle = variable ;
target_ref = variable | parameter | string_literal ;
proposition_tuple
= "(", term, ",", predicate_atom, ",", term, ")"
| "(", "id", ":", scalar_or_parameter, ")" ;
predicate_atom = string_literal | parameter | variable ;
term = variable
| parameter
| literal
| object_pattern
| proposition_tuple ;
object_pattern = "{",
[ pattern_member, { ",", pattern_member } ],
"}" ;
pattern_member = field_name, ":", pattern_value ;
pattern_value = variable
| parameter
| literal
| array_pattern
| object_pattern
| proposition_tuple ;
array_pattern = "[",
[ pattern_value, { ",", pattern_value } ],
"]" ;
mutation_value = field_access
| variable
| parameter
| literal
| array_literal
| object_literal
| function_call ;
scalar_or_parameter
= parameter | literal ;
(* Registered update-expression functions include ADD, MUL, CLAMP, COALESCE.
Syntax remains open to registered/Profile-defined deterministic functions;
semantic validation decides whether the function is legal for a field. *)