AI Assistant Quickstart
CCL Implementation Guide for AI Assistants
Section titled “CCL Implementation Guide for AI Assistants”This guide helps AI assistants (Claude, GPT, etc.) quickly understand CCL and help users implement parsers and test runners.
Quick Facts About CCL
Section titled “Quick Facts About CCL”- CCL = Categorical Configuration Language
- Based on category theory (monoid composition)
- NOT like YAML/JSON - uses recursive fixed-point parsing
- All identifiers use snake_case (never hyphens)
- Key-value pairs are the entire format
Standard Terminology (Use These Exact Terms)
Section titled “Standard Terminology (Use These Exact Terms)”Functions (What Implementers Build)
Section titled “Functions (What Implementers Build)”Core (Required):
parse- Convert text to flat key-value entries (public API)build_hierarchy- Build nested objects via recursive parsing (public API)- Internally uses
parse_indentedhelper (private/internal - strips common leading whitespace before parsing nested values)
- Internally uses
Typed Access (Optional):
get_string,get_int,get_bool,get_float,get_list
Processing (Optional):
filter- Remove comment entries (keys starting with/)compose- Monoid composition of entry lists
Formatting (Optional):
canonical_format- Standardized outputround_trip- Parse → format → parse identity
Features (Optional Language Capabilities)
Section titled “Features (Optional Language Capabilities)”comments-/=comment syntaxempty_keys- List items with= valuemultiline- Multi-line value supportunicode- Unicode content handlingwhitespace- Complex whitespace preservationexperimental_dotted_keys- NOT STANDARD - experimental only
Behaviors (Mutually Exclusive Choices)
Section titled “Behaviors (Mutually Exclusive Choices)”boolean_strictvsboolean_lenientcrlf_normalize_to_lfvscrlf_preserve_literaltabs_preservevstabs_to_spacesstrict_spacingvsloose_spacinglist_coercion_enabledvslist_coercion_disabled
Variants (Specification Versions)
Section titled “Variants (Specification Versions)”proposed_behavior- Proposed specification behaviorreference_compliant- OCaml reference implementation behavior
How CCL Differs from YAML/JSON
Section titled “How CCL Differs from YAML/JSON”CCL uses recursive fixed-point parsing - fundamentally different from YAML/JSON:
- Parse text to flat entries - Split on first
= - Build hierarchy from indentation - Group by indentation level
- Recursively parse values - If value contains
=, parse it as CCL - Fixed point - Stop when values are plain strings (no more
=)
Example:
database = host = localhost port = 5432Parsing steps:
- Parse:
Entry("database", "\n host = localhost\n port = 5432") - Value contains
=→ parse recursively - Result:
{database: {host: "localhost", port: "5432"}} - Fixed point: “localhost” and “5432” have no
=→ done
Key difference: YAML/JSON parse structure directly. CCL parses key-value pairs recursively.
Test Data Format (Flat Format)
Section titled “Test Data Format (Flat Format)”Implementers use the flat format in generated_tests/ directory.
Test Structure:
{ "name": "test_name_validation", "input": "key = value", "validation": "parse", "expected": { "count": 1, "entries": [{"key": "key", "value": "value"}] }, "functions": ["parse"], "features": [], "behaviors": [], "variants": []}Key Fields:
validation- Which CCL function to testfunctions- Required functions for this testfeatures- Required optional featuresbehaviors- Implementation behavior choicesconflicts- Mutually exclusive options
Building a Test Runner
Section titled “Building a Test Runner”Complete Example (Pseudocode)
Section titled “Complete Example (Pseudocode)”// 1. Load test dataconst tests = JSON.parse(readFile('generated_tests/api_core_ccl_parsing.json'));
// 2. Define implementation capabilitiesconst capabilities = { functions: ['parse', 'build_hierarchy', 'get_string', 'get_int'], features: ['comments', 'empty_keys'], behaviors: ['crlf_normalize_to_lf', 'boolean_strict'], variants: ['reference_compliant']};
// 3. Filter tests based on capabilitiesfunction isTestSupported(test, capabilities) { // All required functions must be implemented const functionsOk = test.functions.every(fn => capabilities.functions.includes(fn) );
// All required features must be supported const featuresOk = test.features.every(feat => capabilities.features.includes(feat) );
// No conflicting behaviors const noConflictingBehaviors = !test.conflicts?.behaviors?.some(b => capabilities.behaviors.includes(b) );
// No conflicting variants const noConflictingVariants = !test.conflicts?.variants?.some(v => capabilities.variants.includes(v) );
return functionsOk && featuresOk && noConflictingBehaviors && noConflictingVariants;}
const supportedTests = tests.filter(t => isTestSupported(t, capabilities));
// 4. Run testssupportedTests.forEach(test => { switch (test.validation) { case 'parse': const actual = parse(test.input); assert.deepEqual(actual, test.expected.entries); assert.equal(actual.length, test.expected.count); break;
case 'build_hierarchy': const entries = parse(test.input); const obj = buildHierarchy(entries); assert.deepEqual(obj, test.expected.object); break;
case 'get_string': const ccl = buildHierarchy(parse(test.input)); const value = getString(ccl, ...test.args); assert.equal(value, test.expected.value); break;
// ... other validation types }});Type-Safe Filtering Pattern
Section titled “Type-Safe Filtering Pattern”interface Capabilities { functions: string[]; features: string[]; behaviors: string[]; variants: string[];}
interface Test { validation: string; functions: string[]; features: string[]; behaviors: string[]; variants: string[]; conflicts?: { behaviors?: string[]; variants?: string[]; };}
function getCompatibleTests( tests: Test[], capabilities: Capabilities): Test[] { return tests.filter(test => { // Direct array operations - no string parsing needed const functionsSupported = test.functions.every(fn => capabilities.functions.includes(fn) );
const featuresSupported = test.features.every(feat => capabilities.features.includes(feat) );
const hasConflictingBehavior = test.conflicts?.behaviors?.some(b => capabilities.behaviors.includes(b) );
const hasConflictingVariant = test.conflicts?.variants?.some(v => capabilities.variants.includes(v) );
return functionsSupported && featuresSupported && !hasConflictingBehavior && !hasConflictingVariant; });}Function-Based Progressive Implementation
Section titled “Function-Based Progressive Implementation”Implement CCL functions in this order:
Stage 1: Core Parsing (Required)
Section titled “Stage 1: Core Parsing (Required)”163 tests for parse
- Split lines on first
= - Trim keys, preserve value whitespace
- Handle multiline via indentation
77 tests for build_hierarchy
- Implement internal
parse_indentedhelper (not public API) that strips common leading whitespace from multiline values - Recursively parse entry values using this helper
- Fixed-point algorithm: stop when values contain no
= - Create nested objects from flat entries
Stage 2: Typed Access (Optional - 84 tests total)
Section titled “Stage 2: Typed Access (Optional - 84 tests total)”get_string- 7 tests (28 assertions)get_int- 11 tests (47 assertions)get_bool- 12 tests (49 assertions)get_float- 6 tests (28 assertions)get_list- 48 tests (186 assertions)
Stage 3: Processing (Optional - 38 tests total)
Section titled “Stage 3: Processing (Optional - 38 tests total)”filter- 3 tests - Remove comment entriescompose- 9 tests - Monoid compositioncanonical_format- 14 tests - Standardized outputround_trip- 12 tests - Format → parse identity
Experimental (NOT Standard Progression)
Section titled “Experimental (NOT Standard Progression)”- Dotted keys - 10 tests - Explicitly experimental
Common AI Assistant Pitfalls
Section titled “Common AI Assistant Pitfalls”❌ Don’t Use Hyphens
Section titled “❌ Don’t Use Hyphens”- Wrong:
build-hierarchy,get-string,dotted-keys - Right:
build_hierarchy,get_string,experimental_dotted_keys
❌ Don’t Confuse Formats
Section titled “❌ Don’t Confuse Formats”- Source format (
source_tests/) - For test suite maintainers - Flat format (
generated_tests/) - For implementers (use this one)
❌ Don’t Include Dotted Keys in Standard Progression
Section titled “❌ Don’t Include Dotted Keys in Standard Progression”- Dotted keys are experimental
- Not part of standard CCL implementation path
- Clearly mark as experimental if supporting
❌ Don’t Use Old Test Counts
Section titled “❌ Don’t Use Old Test Counts”- Old: 26/56/135 tests (outdated)
- Old: 452 assertions, 167 tests (outdated)
- Current: 180 tests, 375 assertions
❌ Don’t Parse Like YAML/JSON
Section titled “❌ Don’t Parse Like YAML/JSON”- CCL uses recursive fixed-point parsing
- Fundamentally different algorithm
- See “How CCL Works” section above
Test Suite Repository
Section titled “Test Suite Repository”GitHub: https://github.com/tylerbutler/ccl-test-data
Test Files:
- All in
generated_tests/directory - JSON format with typed fields
- Use
.jsonextension
Documentation:
- Implementation guides in repository README
- Test filtering documentation available
- Progressive implementation roadmap
Quick Reference Card
Section titled “Quick Reference Card”TERMINOLOGY: Use snake_case everywhereFUNCTIONS: parse, build_hierarchy, get_*, filter, composeFEATURES: comments, empty_keys, multiline, unicode, whitespaceEXPERIMENTAL: experimental_dotted_keys (NOT standard)FORMAT: Use flat format (generated_tests/) for implementersALGORITHM: Recursive fixed-point parsing (NOT like YAML/JSON)TEST COUNTS: 180 tests, 375 assertions (current as of 2025-11-19)