Skip to content

Conformance Levels

CCL conformance is layered. An implementation can be fully conformant while exposing only a small core, and can opt into successive layers by declaring the relevant tags. This page maps the existing tag taxonomy onto four tiers so implementers can see at a glance what’s required, what’s a choice, what’s optional, and what’s experimental.

This page is a synthesis. The normative source for each tag is the page linked from its row.

Everything in this tier must work the same in every conformant implementation. There is no opt-out.

ConcernTag(s)Reference
Parsing — produces a CCL tree from a stringfunction parseparse
Building a hierarchical map from the parsed treefunction build_hierarchybuild_hierarchy
Commentsfeature:commentsFeatures — comments
Empty-key list entriesfeature:empty_keysFeatures — empty_keys
Multiline value continuationfeature:multiline_continuationFeatures — multiline_continuation
Multiline keysfeature:multiline_keysFeatures — multiline_keys
UTF-8 in keys and valuesfeature:unicodeFeatures — unicode
Whitespace trimming on keys and valuesfeature:whitespaceFeatures — whitespace
Tabs preserved literally inside valuesfeature:tab_in_value_preservedFeatures — tab_in_value_preserved
Top-level indentation handled (one of the two strategies; see Tier 2)feature:toplevel_indent_strip or behavior pairFeatures — toplevel_indent_strip

In addition, every implementation must obey the canonical Decisions (bare-list shape, CRLF nested handling). These are not optional features — they are normative resolutions of spec ambiguities.

Test-suite filtering: A core-only implementation declares the feature:* tags above and no behaviors beyond what’s needed to disambiguate Tier 2 conflicts. Tests that require any tag the implementation hasn’t declared are skipped.

Tier 2 — Behavior Choices (Required to declare, free to choose)

Section titled “Tier 2 — Behavior Choices (Required to declare, free to choose)”

Tier 2 is “you must pick one option from each conflict pair, and tests that assume the other option are skipped.” There is no neutral position — every implementation has a choice baked in even if it didn’t make one explicitly.

ConflictOptionsReference
Continuation tab handlingcontinuation_tab_to_space continuation_tab_preserveBehavior Reference — Tab Handling
Top-level indentation strategytoplevel_indent_strip toplevel_indent_preserveBehavior Reference — Continuation Baseline, Continuation Lines
Delimiterdelimiter_first_equals delimiter_prefer_spacedBehavior Reference — Delimiter Mode
Line endingscrlf_normalize_to_lf crlf_preserve_literalBehavior Reference — Line Endings, CRLF Handling in Nested Structures
Indentation output styleindent_spaces indent_tabsBehavior Reference — Indentation Style
Array orderarray_order_insertion array_order_lexicographicBehavior Reference — Array Ordering
Boolean parsing strictnessboolean_strict boolean_lenientBehavior Reference — Boolean Parsing
List coercionlist_coercion_enabled list_coercion_disabledBehavior Reference — List Coercion

The canonical bundle is the reference_compliant variant, which selects the OCaml reference implementation’s choice for each pair. New implementations should target it unless they have a specific reason to diverge.

For the complete list of conflict pairs and the meaning of each option, see the Behavior Reference.

Tier 3 is genuinely optional. An implementation can omit everything here and still be conformant on Tier 1 + Tier 2. Tests for Tier 3 features are filtered out for implementations that don’t declare them.

ConcernTagReference
Typed accessors (get_string, get_int, get_bool, get_float, get_list)feature:optional_typed_accessorsFeatures — optional_typed_accessors, Functions — Typed Access
Filtering (e.g. stripping comments)function filterfilter
Composition / merging of CCL documentsfunction composecompose
Pretty printingfunction printprint
Canonical formattingfunction canonical_formatcanonical_format
Lossless round-tripfunction round_tripround_trip
Convenience wrapper for parsing and hierarchy buildingfunction loadload

Optional functions are documented in Functions Reference; the test suite exercises them only when an implementation declares the corresponding tag in its capabilities list.

Tier 4 is explicitly opt-in and may change. No implementation needs to support these to be conformant at any other tier, and the test suite tags them so they can be excluded.

ConcernTagReference
Dotted-key expansion (expand_dotted)feature:experimental_dotted_keysFeatures — experimental_dotted_keys, Dotted Keys Explained, expand_dotted

Experimental tags exist to let implementations and consumers prototype an idea without committing the rest of the ecosystem to it. If an experimental feature stabilises, it graduates to Tier 3 (or, if it changes how the language is parsed, to Tier 1 with a corresponding feature tag).

  • “What’s the minimum I need to ship?” Tier 1 + a declared choice for each Tier 2 conflict. reference_compliant is the safe default.
  • “Can I skip typed accessors?” Yes — they’re Tier 3.
  • “Can I treat database.host as nested?” Only via expand_dotted (Tier 4, experimental). Without that, dotted keys are literal strings — see Dotted Keys Explained.
  • “My output differs from another implementation.” Check Tier 2 first — that’s where legitimate differences live. If both implementations declare the same option for every conflict pair and still disagree, one of them has a bug. See Troubleshooting — Cross-Implementation Symptoms.