A1 RS-1 normative grammar
RS-1 grammar (BNF)
A formal grammar for the .kolm manifest, recipes, and receipt. If you write a parser to this, you can validate any RS-1 artifact without reading the prose.
Notation: extended BNF. ::= means “is defined as”. | means alternatives. ? means optional. * means zero-or-more. + means one-or-more. Quoted strings are literal. WS is implicit between tokens at JSON boundaries.
Top-level archive
; A .kolm is a deterministic ZIP. Members appear in this order. archive ::= manifest recipes evals receipt model_ptr lora? index? manifest ::= "manifest.json" manifest_doc recipes ::= "recipes.json" recipes_doc evals ::= "evals.jsonl" jsonl_lines receipt ::= "receipt.json" receipt_doc model_ptr ::= "model.ptr" model_ptr_doc lora ::= "lora.bin" bytes index ::= "index.sqlite-vec" bytes
manifest.json
manifest_doc ::= "{" m_spec "," m_schema "," m_task "," m_compiled "," m_base_model "," m_recipe_registry "," m_k_score "," m_compiler "}" m_spec ::= "\"spec\"" ":" "\"rs-1\"" m_schema ::= "\"schema\"" ":" "\"manifest-v0.1\"" m_task ::= "\"task\"" ":" string m_compiled ::= "\"compiled_at\"" ":" iso_8601_z m_base_model ::= "\"base_model\"" ":" "{" "\"name\"" ":" string "," "\"sha256\"" ":" hex64 "}" m_recipe_registry ::= "\"recipe_registry\"" ":" "{" "\"version\"" ":" date_or_tag "," "\"url\"" ":" https_url "}" m_k_score ::= "\"k_score\"" ":" "{" "\"spec\"" ":" "\"k-score-1\"" "," "\"composite\"" ":" unit_float "," "\"accuracy\"" ":" unit_float "," "\"coverage\"" ":" unit_float "," "\"size_bytes\"" ":" u64 "," "\"p50_latency_us\"" ":" u64 "," "\"cost_usd_per_call\"" ":" non_neg_float "}" m_compiler ::= "\"compiler\"" ":" "{" "\"name\"" ":" "\"kolm\"" "," "\"version\"" ":" semver "}"
recipes.json
recipes_doc ::= "{" "\"recipes\"" ":" "[" recipe_list "]" "}" recipe_list ::= recipe ( "," recipe )* | ; empty recipe ::= "{" "\"id\"" ":" id_slug "," "\"shape\"" ":" string "," "\"tokens\"" ":" "[" string_list "]" "," "\"coverage\"" ":" unit_float "}"
receipt.json
receipt_doc ::= "{" "\"spec\"" ":" "\"receipt-v0.1\"" "," "\"alg\"" ":" "\"HMAC-SHA256\"" "," "\"signed_at\"" ":" iso_8601_z "," "\"signer\"" ":" signer_id "," "\"chain\"" ":" "[" chain_link+ "]" "," "\"registry_signature\"" ":" b64 "," "\"signature\"" ":" b64 "}" chain_link ::= "{" "\"member\"" ":" member_name "," "\"sha256\"" ":" hex64 ( "," "\"optional\"" ":" bool )? "}" member_name ::= "\"manifest.json\"" | "\"recipes.json\"" | "\"evals.jsonl\"" | "\"model.ptr\"" | "\"lora.bin\"" | "\"index.sqlite-vec\"" signer_id ::= string ; e.g. "kolm-cloud@kolm.ai"
model.ptr
model_ptr_doc ::= "{" "\"kind\"" ":" model_kind "," "\"name\"" ":" string "," "\"sha256\"" ":" hex64 "," "\"url\"" ":" https_url "}" model_kind ::= "\"huggingface\"" | "\"ollama\"" | "\"local\""
Lexical primitives
string ::= "\"" json_string_chars "\"" hex64 ::= "\"" [0-9a-f]{64} "\"" b64 ::= "\"" [A-Za-z0-9+/=]+ "\"" u64 ::= [0-9]+ ; 0..2^64-1 unit_float ::= "0" | "1" | "0." [0-9]+ | "1.0" ; 0.0..1.0 inclusive non_neg_float ::= [0-9]+ ( "." [0-9]+ )? bool ::= "true" | "false" iso_8601_z ::= "\"" [0-9]{4}"-"[0-9]{2}"-"[0-9]{2} "T"[0-9]{2}":"[0-9]{2}":"[0-9]{2}"Z\"" date_or_tag ::= "\"" [0-9]{4}"-"[0-9]{2}"-"[0-9]{2} "\"" | tag_string id_slug ::= "\"" [a-z0-9-]+ "\"" semver ::= "\"" [0-9]+"."[0-9]+"."[0-9]+ ( "-" [a-z0-9.-]+ )? "\"" https_url ::= "\"https://" [^"]+ "\"" tag_string ::= "\"" [a-z0-9._-]+ "\"" jsonl_lines ::= ( json_object "\n" )* json_object ::= ; per RFC 8259 string_list ::= string ( "," string )* | json_string_chars ::= ; per RFC 8259, with sorted keys at parent scope bytes ::= ; opaque; SHA-256 must match the chain link
Implementation notes
- Determinism. JSON keys MUST be emitted in lexicographic order. Whitespace MUST be a single space after
:and,with no trailing whitespace, and a final\n. The grammar allows other whitespace; compilers MUST not emit it. - ZIP framing. Members use STORE (no compression). Timestamps fixed at
1980-01-01T00:00:00Z. External attributes zeroed. - Unknown keys. Parsers SHOULD reject unknown keys at the top level of
manifest.jsonandreceipt.json. Insidek_scorethey MAY accept unknown keys for forward compatibility. - Future versions. A breaking change bumps
spectors-2. Non-breaking additions get new optional members and bump only theschemafield.
Test fixtures
Reference artifacts that conform to this grammar are published in the registry. Pull any one of them and run your parser against the bytes:
# pick the top of the leaderboard curl -s https://kolm.ai/v1/public/concepts | jq '.concepts[0].id' # download its .kolm curl -sLO https://kolm.ai/v1/registry/<id>/artifact # verify against this grammar kolm verify ./<id>.kolm --strict --grammar rs-1