kumi 0.0.0 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (92) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +113 -3
  3. data/CHANGELOG.md +21 -1
  4. data/CLAUDE.md +387 -0
  5. data/README.md +257 -20
  6. data/docs/development/README.md +120 -0
  7. data/docs/development/error-reporting.md +361 -0
  8. data/documents/AST.md +126 -0
  9. data/documents/DSL.md +154 -0
  10. data/documents/FUNCTIONS.md +132 -0
  11. data/documents/SYNTAX.md +367 -0
  12. data/examples/deep_schema_compilation_and_evaluation_benchmark.rb +106 -0
  13. data/examples/federal_tax_calculator_2024.rb +112 -0
  14. data/examples/wide_schema_compilation_and_evaluation_benchmark.rb +80 -0
  15. data/lib/generators/trait_engine/templates/schema_spec.rb.erb +27 -0
  16. data/lib/kumi/analyzer/constant_evaluator.rb +51 -0
  17. data/lib/kumi/analyzer/passes/definition_validator.rb +42 -0
  18. data/lib/kumi/analyzer/passes/dependency_resolver.rb +71 -0
  19. data/lib/kumi/analyzer/passes/input_collector.rb +55 -0
  20. data/lib/kumi/analyzer/passes/name_indexer.rb +24 -0
  21. data/lib/kumi/analyzer/passes/pass_base.rb +67 -0
  22. data/lib/kumi/analyzer/passes/toposorter.rb +72 -0
  23. data/lib/kumi/analyzer/passes/type_checker.rb +139 -0
  24. data/lib/kumi/analyzer/passes/type_consistency_checker.rb +45 -0
  25. data/lib/kumi/analyzer/passes/type_inferencer.rb +125 -0
  26. data/lib/kumi/analyzer/passes/unsat_detector.rb +107 -0
  27. data/lib/kumi/analyzer/passes/visitor_pass.rb +41 -0
  28. data/lib/kumi/analyzer.rb +54 -0
  29. data/lib/kumi/atom_unsat_solver.rb +349 -0
  30. data/lib/kumi/compiled_schema.rb +41 -0
  31. data/lib/kumi/compiler.rb +127 -0
  32. data/lib/kumi/domain/enum_analyzer.rb +53 -0
  33. data/lib/kumi/domain/range_analyzer.rb +83 -0
  34. data/lib/kumi/domain/validator.rb +84 -0
  35. data/lib/kumi/domain/violation_formatter.rb +40 -0
  36. data/lib/kumi/domain.rb +8 -0
  37. data/lib/kumi/error_reporter.rb +164 -0
  38. data/lib/kumi/error_reporting.rb +95 -0
  39. data/lib/kumi/errors.rb +116 -0
  40. data/lib/kumi/evaluation_wrapper.rb +20 -0
  41. data/lib/kumi/explain.rb +282 -0
  42. data/lib/kumi/export/deserializer.rb +39 -0
  43. data/lib/kumi/export/errors.rb +12 -0
  44. data/lib/kumi/export/node_builders.rb +140 -0
  45. data/lib/kumi/export/node_registry.rb +38 -0
  46. data/lib/kumi/export/node_serializers.rb +156 -0
  47. data/lib/kumi/export/serializer.rb +23 -0
  48. data/lib/kumi/export.rb +33 -0
  49. data/lib/kumi/function_registry/collection_functions.rb +92 -0
  50. data/lib/kumi/function_registry/comparison_functions.rb +31 -0
  51. data/lib/kumi/function_registry/conditional_functions.rb +36 -0
  52. data/lib/kumi/function_registry/function_builder.rb +92 -0
  53. data/lib/kumi/function_registry/logical_functions.rb +42 -0
  54. data/lib/kumi/function_registry/math_functions.rb +72 -0
  55. data/lib/kumi/function_registry/string_functions.rb +54 -0
  56. data/lib/kumi/function_registry/type_functions.rb +51 -0
  57. data/lib/kumi/function_registry.rb +138 -0
  58. data/lib/kumi/input/type_matcher.rb +92 -0
  59. data/lib/kumi/input/validator.rb +52 -0
  60. data/lib/kumi/input/violation_creator.rb +50 -0
  61. data/lib/kumi/input.rb +8 -0
  62. data/lib/kumi/parser/build_context.rb +25 -0
  63. data/lib/kumi/parser/dsl.rb +12 -0
  64. data/lib/kumi/parser/dsl_cascade_builder.rb +125 -0
  65. data/lib/kumi/parser/expression_converter.rb +58 -0
  66. data/lib/kumi/parser/guard_rails.rb +43 -0
  67. data/lib/kumi/parser/input_builder.rb +94 -0
  68. data/lib/kumi/parser/input_proxy.rb +29 -0
  69. data/lib/kumi/parser/parser.rb +66 -0
  70. data/lib/kumi/parser/schema_builder.rb +172 -0
  71. data/lib/kumi/parser/sugar.rb +108 -0
  72. data/lib/kumi/schema.rb +49 -0
  73. data/lib/kumi/schema_instance.rb +43 -0
  74. data/lib/kumi/syntax/declarations.rb +23 -0
  75. data/lib/kumi/syntax/expressions.rb +30 -0
  76. data/lib/kumi/syntax/node.rb +46 -0
  77. data/lib/kumi/syntax/root.rb +12 -0
  78. data/lib/kumi/syntax/terminal_expressions.rb +27 -0
  79. data/lib/kumi/syntax.rb +9 -0
  80. data/lib/kumi/types/builder.rb +21 -0
  81. data/lib/kumi/types/compatibility.rb +86 -0
  82. data/lib/kumi/types/formatter.rb +24 -0
  83. data/lib/kumi/types/inference.rb +40 -0
  84. data/lib/kumi/types/normalizer.rb +70 -0
  85. data/lib/kumi/types/validator.rb +35 -0
  86. data/lib/kumi/types.rb +64 -0
  87. data/lib/kumi/version.rb +1 -1
  88. data/lib/kumi.rb +7 -3
  89. data/scripts/generate_function_docs.rb +59 -0
  90. data/test_impossible_cascade.rb +51 -0
  91. metadata +93 -10
  92. data/sig/kumi.rbs +0 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0ed9109766ab10fdf560d0597cea8ea62745e031f0b520d5e491e630d2114247
4
- data.tar.gz: 1aef5090952191e3d6c3a67a80e64d0c826749e1f9d6be277c9704904ef96a30
3
+ metadata.gz: 46d129da8737c28750b4aa51f1234bbce39b047eac599d248735ae6b5eff199c
4
+ data.tar.gz: 045e55121094f5e8a5a2cb2512b745c2d82c9de7f3dc0fcb5d1f9fbe88764683
5
5
  SHA512:
6
- metadata.gz: 4c4337723f1a6aa34a7e64ecbbb303d5e6cd295a812248e6a9afde8bfd4718bb9f4668ae9c9dc039156c344b4b06fa6e8cc789cd93892fb2f4c3eb3a11749d31
7
- data.tar.gz: 51efeb943d1c0dc9d1eb8f3de4521248b6d3f3ae2fff8a1172f37d5932a816c63a28b2ce068d2c2d594c06ecc3c2a479ae46835ef089cbe6f785543cbf0ae543
6
+ metadata.gz: 207e8e9c14f083c660af9d16e418f8f7b2ee753989adb22c107acfb062bdedb334160a7978f6ad33dce463dd8faee6b7016068689f0c3678ebf52d117328cef2
7
+ data.tar.gz: 7cddb20e40da3b55361281abaebd37a12276b1e4e6418453aa4f199ec680eaff714060411f0b0b5a3faf0e199161f3dddc3f2c94da2bd8e3a3e2e2ec4321a871
data/.rubocop.yml CHANGED
@@ -1,8 +1,118 @@
1
+ plugins:
2
+ - rubocop-performance
3
+ - rubocop-rspec
4
+
1
5
  AllCops:
2
- TargetRubyVersion: 3.1
6
+ NewCops: enable
7
+ TargetRubyVersion: 3.0
8
+ SuggestExtensions: false
9
+ Exclude:
10
+ - 'bin/*'
11
+ - 'spec/fixtures/**/*'
12
+ - 'examples/**/*' # Examples may use deprecated syntax
13
+ - '*.txt'
14
+ - 'test_*.rb' # Temporary test files
15
+ - 'spec/integration/performance_spec.rb'
3
16
 
17
+ # Common stylistic choices
4
18
  Style/StringLiterals:
5
19
  EnforcedStyle: double_quotes
6
20
 
7
- Style/StringLiteralsInInterpolation:
8
- EnforcedStyle: double_quotes
21
+ Style/Documentation:
22
+ Enabled: false
23
+
24
+ Style/OpenStructUse:
25
+ Enabled: false # Used in AST nodes and test fixtures
26
+
27
+ # Naming conventions - allow underscores in symbols for tax codes, etc.
28
+ Naming/VariableNumber:
29
+ Enabled: false
30
+
31
+ # Layout
32
+ Layout/LineLength:
33
+ Max: 140
34
+
35
+ # Metrics - Reasonable limits for a DSL/compiler project
36
+ Metrics/MethodLength:
37
+ Max: 20
38
+ Exclude:
39
+ - 'lib/kumi/function_registry.rb' # Large function registry
40
+ - 'lib/kumi/function_registry/**/*' # Function registry modules with data definitions
41
+ - 'lib/kumi/analyzer/passes/**/*' # Analyzer passes often need longer methods
42
+ - 'lib/kumi/types.rb' # Type system operations
43
+ - 'lib/kumi/types/**/*' # Type system modules
44
+ - 'lib/kumi/runner.rb' # Complex runner methods
45
+ - 'spec/**/*' # Test files often need longer methods
46
+
47
+ Metrics/AbcSize:
48
+ Max: 20
49
+ Exclude:
50
+ - 'lib/kumi/function_registry.rb' # Large function registry
51
+ - 'lib/kumi/function_registry/**/*' # Function registry modules with data definitions
52
+ - 'lib/kumi/analyzer/passes/**/*' # Complex analyzer logic
53
+ - 'lib/kumi/types.rb' # Type system operations
54
+ - 'lib/kumi/types/**/*' # Type system modules
55
+ - 'lib/kumi/runner.rb' # Complex runner methods
56
+ - 'spec/**/*' # Test files often have higher ABC
57
+
58
+ Metrics/CyclomaticComplexity:
59
+ Max: 10
60
+ Exclude:
61
+ - 'lib/kumi/analyzer/passes/**/*' # Complex analyzer logic
62
+ - 'lib/kumi/types.rb' # Type system operations
63
+ - 'lib/kumi/types/**/*' # Type system modules
64
+ - 'lib/kumi/runner.rb' # Complex runner methods
65
+
66
+ Metrics/PerceivedComplexity:
67
+ Max: 10
68
+ Exclude:
69
+ - 'lib/kumi/analyzer/passes/**/*' # Complex analyzer logic
70
+ - 'lib/kumi/types.rb' # Type system operations
71
+ - 'lib/kumi/types/**/*' # Type system modules
72
+
73
+ Metrics/ParameterLists:
74
+ Max: 6
75
+ Exclude:
76
+ - 'lib/kumi/analyzer/passes/dependency_resolver.rb' # Complex dependency analysis
77
+ - 'lib/kumi/function_registry.rb' # Metadata registration
78
+
79
+ Metrics/ModuleLength:
80
+ Max: 150
81
+ Exclude:
82
+ - 'lib/kumi/function_registry.rb' # Large function registry
83
+
84
+ # Allow missing super in base classes that are designed for inheritance
85
+ Lint/MissingSuper:
86
+ Exclude:
87
+ - 'lib/kumi/analyzer/passes/pass_base.rb' # Base class for analyzer passes
88
+ - 'lib/kumi/types.rb' # Type system value objects
89
+
90
+ # RSpec-specific configuration
91
+ RSpec:
92
+ Enabled: true
93
+
94
+ RSpec/MultipleExpectations:
95
+ Enabled: false
96
+
97
+ RSpec/ExampleLength:
98
+ Max: 30
99
+ Exclude:
100
+ - 'spec/kumi/export/comprehensive_integration_spec.rb' # Comprehensive integration tests need longer examples
101
+
102
+ RSpec/MultipleMemoizedHelpers:
103
+ Max: 10
104
+
105
+ RSpec/VerifiedDoubleReference:
106
+ Enabled: false # May require significant test refactoring
107
+
108
+ RSpec/DescribeClass:
109
+ Enabled: false # Integration tests don't always test specific classes
110
+
111
+ RSpec/ContextWording:
112
+ Enabled: false # Allow flexible context naming
113
+
114
+ RSpec/ExpectActual:
115
+ Enabled: true # Keep this - it's a good practice
116
+
117
+ RSpec/IdenticalEqualityAssertion:
118
+ Enabled: false # Sometimes needed for testing type systems
data/CHANGELOG.md CHANGED
@@ -1,5 +1,25 @@
1
1
  ## [Unreleased]
2
2
 
3
- ## [0.1.0] - 2025-07-06
3
+ ### Changed
4
+ - **BREAKING**: Replaced `StrictCycleChecker` with `AtomUnsatSolver` for stack-safe UNSAT detection
5
+ - Refactored cycle detection to use iterative Kahn's topological sort algorithm instead of recursive DFS
6
+ - Added support for always-false comparison detection (e.g., `100 < 100`)
7
+
8
+ ### Added
9
+ - **Evaluation memoization**: `EvaluationWrapper` struct with `@__schema_cache__` provides automatic caching of computed bindings
10
+ - **Massive performance improvements**: 369x-1,379x speedup on deep dependency chains through intelligent memoization
11
+ - Depth-safe UNSAT detection handles 30k+ node graphs without stack overflow
12
+ - Comprehensive test suite for large graph scenarios (acyclic ladders, cycles, mixed constraints)
13
+ - Enhanced documentation with YARD comments for `AtomUnsatSolver` module
14
+ - Extracted `StrictInequalitySolver` module for clear separation of cycle detection logic
15
+
16
+ ### Performance
17
+ - **Stack-safe UNSAT detection**: Eliminates `SystemStackError` in constraint analysis for 30k+ node graphs
18
+ - **Fixed gather_atoms recursion**: Made AST traversal iterative to handle deep dependency chains
19
+ - Sub-millisecond performance on 10k-20k node constraint graphs with cycle detection
20
+ - Maintained identical UNSAT detection correctness for all existing scenarios
21
+ - **Note**: Deep schemas (2500+ dependencies) may still hit Ruby stack limits in compilation/evaluation phases
22
+
23
+ ## [0.1.0] - 2025-07-01
4
24
 
5
25
  - Initial release
data/CLAUDE.md ADDED
@@ -0,0 +1,387 @@
1
+ # CLAUDE.md
2
+
3
+ !! Remember, this gem is not on production yet, so no backward compatilibity is necessary. But do not change the public interfaces (e.g. DSL, Schema) without explicitly requested or demanded.
4
+ !! We are using zeitwerk, i.e.: no requires
5
+ !! Do not care about linter or coverage unless asked to do so.
6
+
7
+ This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
8
+
9
+ ## Project Overview
10
+
11
+ Kumi is a declarative decision-modeling compiler for Ruby that transforms complex business rules into executable dependency graphs. It features a multi-pass analyzer that validates rule interdependencies, detects cycles, infers types, and generates optimized evaluation functions. The system separates input field declarations from business logic through an explicit input block syntax.
12
+
13
+ ## Development Commands
14
+
15
+ ### Testing
16
+ - `bundle exec rspec` - Run all tests
17
+ - `bundle exec rspec spec/path/to/specific_spec.rb` - Run specific test file
18
+ - `bundle exec rspec spec/path/to/specific_spec.rb:123` - Run specific test at line
19
+
20
+ ### Linting & Code Quality
21
+ - `bundle exec rubocop` - Run RuboCop linter
22
+ - `bundle exec rubocop -a` - Auto-fix RuboCop issues where possible
23
+ - `rake` - Run default task (includes rspec and rubocop)
24
+
25
+ ### Gem Management
26
+ - `bundle install` - Install dependencies
27
+ - `gem build kumi.gemspec` - Build the gem
28
+ - `gem install ./kumi-*.gem` - Install locally built gem
29
+
30
+ ## Architecture Overview
31
+
32
+ ### Core Components
33
+
34
+ **Schema System** (`lib/kumi/schema.rb`):
35
+ - Entry point that ties together parsing, analysis, and compilation
36
+ - Provides the `schema(&block)` DSL method that builds the syntax tree, runs analysis, and compiles to executable form
37
+ - Generates a `Runner` instance for executing queries against input data
38
+
39
+ **Parser** (`lib/kumi/parser/`):
40
+ - `dsl.rb` - Main DSL parser that converts Ruby block syntax into AST nodes
41
+ - `dsl_builder_context.rb` - Context for building DSL elements with input/value/trait methods
42
+ - `dsl_cascade_builder.rb` - Specialized builder for cascade expressions
43
+ - `dsl_proxy.rb` - Proxy object for method delegation during parsing
44
+ - `input_dsl_proxy.rb` - Proxy for input block DSL supporting both `key` method and type-specific DSL methods
45
+ - `input_proxy.rb` - Proxy for `input.field_name` references in expressions
46
+
47
+ **Syntax Tree** (`lib/kumi/syntax/`):
48
+ - `node.rb` - Base node class with location tracking
49
+ - `root.rb` - Root schema node containing inputs, attributes, and traits
50
+ - `declarations.rb` - Attribute and trait declaration nodes
51
+ - `expressions.rb` - Expression nodes (calls, lists, cascades)
52
+ - `terminal_expressions.rb` - Terminal nodes (literals, field references, bindings, field declarations)
53
+
54
+ **Analyzer** (`lib/kumi/analyzer.rb`):
55
+ - Multi-pass analysis system that validates schemas and builds dependency graphs
56
+ - **Pass 1**: `name_indexer.rb` - Find all names, check for duplicates
57
+ - **Pass 2**: `input_collector.rb` - Collect field metadata, validate conflicts
58
+ - **Pass 3**: `definition_validator.rb` - Validate basic structure
59
+ - **Pass 4**: `dependency_resolver.rb` - Build dependency graph
60
+ - **Pass 5**: `cycle_detector.rb` - Find circular dependencies
61
+ - **Pass 6**: `toposorter.rb` - Create evaluation order
62
+ - **Pass 7**: `type_inferencer.rb` - Infer types for all declarations
63
+ - **Pass 8**: `type_checker.rb` - Validate function types and compatibility using inferred types
64
+
65
+ **Compiler** (`lib/kumi/compiler.rb`):
66
+ - Transforms analyzed syntax tree into executable lambda functions
67
+ - Maps each expression type to a compilation method
68
+ - Handles function calls via `FunctionRegistry`
69
+ - Produces `CompiledSchema` with executable bindings
70
+
71
+ **Function Registry** (`lib/kumi/function_registry.rb`):
72
+ - Registry of available functions (operators, math, string, logical, collection operations)
73
+ - Supports custom function registration with comprehensive type metadata
74
+ - Each function includes param_types, return_type, arity, and description
75
+ - Core functions include: `==`, `>`, `<`, `add`, `multiply`, `and`, `or`, `clamp`, etc.
76
+ - Maintains backward compatibility with legacy type checking system
77
+ - Function documents are generated by the script ./scripts/generate_function_docs.rb
78
+
79
+ **Runner** (`lib/kumi/runner.rb`):
80
+ - Executes compiled schemas against input data
81
+ - Provides `fetch(key)` for individual value retrieval with caching
82
+ - Provides `slice(*keys)` for batch evaluation
83
+ - Provides `explain(key)` for detailed execution tracing
84
+
85
+ **Input Validation System** (`lib/kumi/input/` and `lib/kumi/domain/`):
86
+ - `input/validator.rb` - Main validation coordinator for type and domain checking
87
+ - `input/type_matcher.rb` - Type validation logic for primitive and complex types
88
+ - `input/violation_creator.rb` - Creates standardized violation objects with detailed messages
89
+ - `domain/validator.rb` - Domain constraint validation (ranges, arrays, procs)
90
+ - `domain/range_analyzer.rb` - Range domain analysis and validation
91
+ - `domain/enum_analyzer.rb` - Enumeration domain analysis and validation
92
+ - `domain/violation_formatter.rb` - Formats domain violation error messages
93
+
94
+ ### Key Patterns
95
+
96
+ **DSL Structure**:
97
+ ```ruby
98
+ schema do
99
+ input do
100
+ # Recommended type-specific DSL methods
101
+ string :field_name
102
+ integer :number_field, domain: 0..100
103
+ array :scores, elem: { type: :float }
104
+ hash :metadata, key: { type: :string }, val: { type: :any }
105
+
106
+ # Fields with no declared type
107
+ any :misc_field
108
+ end
109
+
110
+ trait :name, (expression) # Boolean conditions with new syntax
111
+ value :name, expression # Computed values
112
+ value :name do # Conditional logic
113
+ on condition, result
114
+ base default_result
115
+ end
116
+ end
117
+ ```
118
+
119
+ **IMPORTANT CASCADE CONDITION SYNTAX:**
120
+ In cascade expressions (`value :name do ... end`), trait references use **symbols**, not bare identifiers:
121
+ ```ruby
122
+ value :status do
123
+ on :adult, "Adult Status" # ✅ Correct - use :trait_name symbol
124
+ on :verified, "Verified User"
125
+ base "Unverified"
126
+ end
127
+
128
+ # NOT this:
129
+ value :status do
130
+ on adult, "Adult Status" # ❌ Wrong - don't use bare identifier in cascade
131
+ on verified, "Verified User" # ❌ Wrong
132
+ base "Unverified"
133
+ end
134
+ ```
135
+
136
+ **Input Block System**:
137
+ - **Required**: All schemas must have an `input` block declaring expected fields
138
+ - **Type Declarations**: Preferred via type-specific methods (e.g. `integer :field`, `string :name`, `any :field` for untyped fields)
139
+ - **Complex Types**: Use helper functions: `array(:element_type)` and `hash(:key_type, :value_type)`
140
+ - **Domain Constraints**: Fields can have domains: `integer :age, domain: 18..65` (validated at runtime)
141
+ - **Field Access**: Use `input.field_name` to reference input fields in expressions
142
+ - **Separation**: Input metadata (types, domains) is separate from business logic
143
+
144
+ **Expression Types**:
145
+ - `input.field_name` - Access input data with operator methods (>=, <=, >, <, ==, !=)
146
+ - `ref(:name)` - Reference other declarations
147
+ - `fn(:name, args...)` - Function calls
148
+ - `(expr1) & (expr2)` - Logical AND chaining
149
+ - `[element1, element2]` - Lists
150
+ - Literals (numbers, strings, booleans)
151
+
152
+ **Analysis Flow**:
153
+ 1. Parse DSL → Syntax Tree
154
+ 2. Analyze Syntax Tree → Analysis Result (dependency graph, type information, topo order)
155
+ 3. Compile → Executable Schema
156
+ 4. Execute with Runner
157
+
158
+ **Type System** (`lib/kumi/types.rb`):
159
+ - Simple symbol-based type system for clean and intuitive declaration
160
+ - **Dual Type System**: Declared types (from input blocks) and inferred types (from expressions)
161
+ - Automatic type inference for all declarations based on expression analysis
162
+ - Type primitives: `:string`, `:integer`, `:float`, `:boolean`, `:any`, `:symbol`, `:regexp`, `:time`, `:date`, `:datetime`
163
+ - Collection types: `array(:element_type)` and `hash(:key_type, :value_type)` helper functions
164
+ - Type compatibility checking and unification algorithms for numeric types
165
+ - Enhanced error messages showing type provenance (declared vs inferred)
166
+ - Legacy compatibility constants maintained for backward compatibility
167
+
168
+ ### Examples Directory
169
+
170
+ The `examples/` directory contains comprehensive examples showing Kumi usage patterns:
171
+ - `cascade_demonstration.rb` - Demonstrates cascade logic with UnsatDetector fixes (working)
172
+ - `working_comprehensive_schema.rb` - Complete feature showcase (current best practices, working)
173
+ - `federal_tax_calculator_2024.rb` - Real-world tax calculation example (working)
174
+ - `tax_2024.rb` - Simple tax example with explain functionality (working)
175
+ - `wide_schema_compilation_and_evaluation_benchmark.rb` - Performance benchmark for wide schemas (compilation and evaluation scaling)
176
+ - `deep_schema_compilation_and_evaluation_benchmark.rb` - Performance benchmark for deep dependency chains (stack-safe evaluation)
177
+ - `comprehensive_god_schema.rb` - Complex example (currently has UnsatDetector semantic errors)
178
+
179
+ *Note: Some examples may use deprecated syntax and should be updated to use the new input block system.*
180
+
181
+ ## Test Structure
182
+
183
+ - `spec/kumi/` - Unit tests for core components
184
+ - `spec/integration/` - Integration tests for full workflows
185
+ - `spec/fixtures/` - Test fixtures and sample schemas
186
+ - `spec/support/` - Test helpers (`ast_factory.rb`, `schema_generator.rb`)
187
+
188
+ ## Key Files for Understanding
189
+
190
+ 1. `lib/kumi/schema.rb` - Start here to understand the main API
191
+ 2. `examples/input_block_typing_showcase.rb` - Comprehensive example of current features
192
+ 3. `lib/kumi/analyzer.rb` - Core analysis pipeline with multi-pass system
193
+ 4. `lib/kumi/types.rb` - Static type system implementation
194
+ 5. `lib/kumi/function_registry.rb` - Available functions and extension patterns
195
+ 6. `lib/kumi/analyzer/passes/type_inferencer.rb` - Type inference algorithm
196
+ 7. `lib/kumi/analyzer/passes/type_checker.rb` - Type validation with enhanced error messages
197
+ 8. `spec/kumi/input_block_spec.rb` - Input block syntax and behavior
198
+ 9. `spec/integration/compiler_integration_spec.rb` - End-to-end test examples
199
+ 10. `documents/DSL.md` - Concise DSL syntax reference
200
+ 11. `documents/AST.md` - AST node types and structure reference
201
+ 12. `documents/SYNTAX.md` - Comprehensive sugar vs sugar-free syntax comparison with examples
202
+
203
+ ## Input Block System Details
204
+
205
+ ### Required Input Blocks
206
+ - **All schemas must have an input block** - This is now mandatory
207
+ - Input blocks declare expected fields with optional type and domain constraints
208
+ - **Empty input blocks are allowed** - Use `input {}` for schemas that don't require external data
209
+ - Fields are accessed via `input.field_name` syntax (replaces deprecated `key(:field)`)
210
+
211
+ ### Type System Integration
212
+ - **Declared Types**: Explicit type declarations in input blocks (e.g. `integer :field`, `string :name`, `any :field`)
213
+ - **Inferred Types**: Types automatically inferred from expression analysis
214
+ - **Type Checking**: Validates compatibility between declared and inferred types
215
+ - **Enhanced Errors**: Error messages show type provenance (declared vs inferred)
216
+ - **Helper Functions**: Use `array(:type)` and `hash(:key_type, :value_type)` for complex types
217
+
218
+ ### Parser Components
219
+ - `input_dsl_proxy.rb` - Supports type-specific DSL methods (`integer`, `float`, `string`, `boolean`, `array`, `hash`, `any`)
220
+ - `input_proxy.rb` - Handles `input.field_name` references in expressions
221
+ - `input_collector.rb` - Collects and validates field metadata consistency
222
+
223
+ ### Domain Constraints
224
+ - Can be declared: `integer :age, domain: 18..65`
225
+ - **Implemented**: Domain validation is active and enforced at runtime
226
+ - Supports Range domains (`18..65`), Array domains (`%w[active inactive]`), and Proc domains for custom validation
227
+ - Field metadata includes domain information and runtime validation occurs during `Schema.from()`
228
+
229
+ ### Type Examples
230
+ ```ruby
231
+ input do
232
+ # New type-specific DSL methods (recommended)
233
+ string :name
234
+ integer :age, domain: 18..65
235
+ hash :metadata, key: { type: :string }, val: { type: :any }
236
+
237
+ # For untyped/any fields
238
+ any :misc
239
+ end
240
+ ```
241
+
242
+ ### Trait Syntax Evolution
243
+
244
+ **Current Syntax** (recommended):
245
+ ```ruby
246
+ trait :adult, (input.age >= 18)
247
+ trait :qualified, (input.age >= 21) & (input.score > 80) & (input.verified == true)
248
+ ```
249
+
250
+ **Composite Trait Syntax** (NEW - bare identifier references):
251
+ ```ruby
252
+ # Base traits
253
+ trait :adult, (input.age >= 18)
254
+ trait :verified, (input.verified == true)
255
+ trait :high_score, (input.score > 80)
256
+
257
+ # Composite traits using bare identifier syntax
258
+ trait :eligible, adult & verified & high_score
259
+ trait :mixed, adult & (input.income > 50_000) & verified
260
+
261
+ # Backward compatibility - both syntaxes work together
262
+ trait :legacy_mix, adult & ref(:verified) & (input.score > 90)
263
+ ```
264
+
265
+ **Deprecated Syntax** (with warnings):
266
+ ```ruby
267
+ trait :adult, input.age, :>=, 18 # OLD - shows deprecation warning
268
+ trait :qualified, input.age, :>=, 21, input.score # OLD - shows deprecation warning
269
+ ```
270
+
271
+ **Key Changes**:
272
+ - **NEW**: Bare identifier syntax allows direct trait reference: `adult` instead of `ref(:adult)`
273
+ - New syntax uses parenthesized expressions: `trait :name, (expression)`
274
+ - FieldRef nodes have operator methods that create CallExpression nodes
275
+ - Logical AND chaining via `&` operator (Ruby limitation prevents `&&`)
276
+ - Only AND operations supported to maintain constraint satisfaction system
277
+ - **Backward Compatible**: Both `trait_name` and `ref(:trait_name)` work together
278
+ - Old syntax maintained with deprecation warnings for backward compatibility
279
+
280
+ ## Common Development Tasks
281
+
282
+ ### Adding New Analyzer Passes
283
+ 1. Create pass class inheriting from `PassBase` in `lib/kumi/analyzer/passes/`
284
+ 2. Implement `run(errors)` method that calls `set_state(key, value)` to store results
285
+ 3. Add pass to `PASSES` array in `lib/kumi/analyzer.rb` in correct order
286
+ 4. Consider dependencies on other passes (e.g., TypeChecker needs TypeInferencer)
287
+
288
+ ### Working with AST Nodes
289
+ - All nodes include `Node` module for location tracking
290
+ - Use `spec/support/ast_factory.rb` helpers in tests
291
+ - Field declarations use `FieldDecl` nodes with name, domain, and type
292
+ - Field references use `FieldRef` nodes (from `input.field_name`) with operator methods
293
+ - FieldRef operator methods (>=, <=, >, <, ==, !=) create CallExpression nodes
294
+ - CallExpression `&` method enables logical AND chaining
295
+
296
+ ### Testing Input Block Features
297
+ - See `spec/kumi/input_block_spec.rb` for comprehensive input block tests
298
+ - Use `schema_generator.rb` helper for creating test schemas
299
+ - All integration tests now require input blocks
300
+
301
+ ## Architecture Design Principles
302
+
303
+ - **Multi-pass Analysis**: Each analysis pass has a single responsibility and builds on previous passes
304
+ - **Immutable Syntax Tree**: AST nodes are immutable; analysis results stored separately in analyzer state
305
+ - **Dependency-driven Evaluation**: All computation follows dependency graph to ensure correct order
306
+ - **Type Safety**: Optional but comprehensive type checking without breaking existing schemas
307
+ - **Backward Compatibility**: New features maintain compatibility with existing DSL and APIs
308
+ - **Ruby Integration**: Leverages Ruby's metaprogramming while providing structured analysis
309
+ - **Separation of Concerns**: Input metadata (types, domains) separated from business logic
310
+ - **Class Decomposition**: Large classes split into focused, single-responsibility components following RuboCop guidelines
311
+ - **Delegation Pattern**: Complex operations delegated to specialized analyzer and formatter classes
312
+ - **Unified Error Reporting**: Consistent, localized error messages throughout the system with clear interface patterns
313
+
314
+ ## Code Organization Patterns
315
+
316
+ ### Modular Validation Architecture
317
+ - **Coordinator Classes**: Main classes like `Input::Validator` and `Domain::Validator` coordinate but delegate complex logic
318
+ - **Specialized Analyzers**: Domain-specific classes like `RangeAnalyzer` and `EnumAnalyzer` handle specific constraint types
319
+ - **Formatter Classes**: Dedicated classes like `ViolationFormatter` handle message formatting with consistent patterns
320
+ - **Creator Classes**: Classes like `ViolationCreator` centralize object creation with standardized structure
321
+
322
+ ### Testing Best Practices
323
+ - **Spec Organization**: Tests organized by component with clear separation between unit and integration tests
324
+ - **Error Variable Extraction**: RSpec patterns avoid multiline block chains by extracting error variables for assertion
325
+ - **Shared Contexts**: Use `schema_generator` and other shared contexts for consistent test setup
326
+
327
+ ### RuboCop Compliance
328
+ - **Method Length**: Keep methods under 10 lines through extraction and delegation
329
+ - **Class Length**: Break classes over 100 lines into focused components
330
+ - **Complexity Metrics**: Reduce cyclomatic and ABC complexity through single-responsibility design
331
+ - **Style Consistency**: Follow Ruby style guidelines for readability and maintainability
332
+
333
+ ### Error Reporting Architecture
334
+ - **Unified Interface**: Use `ErrorReporter` module and `ErrorReporting` mixin for consistent error handling
335
+ - **Location Information**: All errors must include proper file:line:column location data
336
+ - **Precise Location Tracking**: Error objects preserve location data in `.location` attribute for programmatic access
337
+ - **User Code Location**: Errors point to actual user DSL code, not internal library files
338
+ - **Backward Compatibility**: Support both legacy `[location, message]` and new `ErrorEntry` formats
339
+ - **Type Categorization**: Errors categorized as `:syntax`, `:semantic`, `:type`, `:runtime`
340
+ - **Enhanced Messaging**: Support for error suggestions, context, and similar name detection
341
+
342
+ ## Development Guides and Standards
343
+
344
+ ### Error Reporting Standards
345
+ **For Parser Classes**:
346
+ ```ruby
347
+ class MyParser
348
+ include ErrorReporting
349
+
350
+ def parse_something
351
+ # Immediate error raising
352
+ raise_syntax_error("Invalid syntax", location: current_location)
353
+ end
354
+ end
355
+ ```
356
+
357
+ **For Analyzer Passes**:
358
+ ```ruby
359
+ class MyAnalyzerPass < PassBase
360
+ def run(errors)
361
+ # Error accumulation with enhanced location
362
+ report_error(errors, "semantic error", location: node.loc, type: :semantic)
363
+
364
+ # Backward compatible method
365
+ add_error(errors, node.loc, "legacy format error")
366
+ end
367
+ end
368
+ ```
369
+ ### Testing Error Scenarios
370
+ - Use `spec/integration/dsl_breakage_spec.rb` patterns for comprehensive error testing
371
+ - Use `spec/integration/potential_breakage_spec.rb` for edge cases break
372
+ - Use `spec/fixtures/location_tracking_test_schema.rb` fixture for testing different syntax error types
373
+ - Test backward compatibility with existing analyzer pass specs
374
+
375
+ ### Key Development Files
376
+ 12. `lib/kumi/error_reporter.rb` - Central error reporting functionality
377
+ 13. `lib/kumi/error_reporting.rb` - Mixin for consistent error interfaces
378
+ 14. `spec/integration/location_tracking_spec.rb` - Comprehensive tests for error location accuracy
379
+ 15. `spec/fixtures/location_tracking_test_schema.rb` - Fixture with intentional syntax errors for location testing
380
+ 16. `ERROR_REPORTING_INTERFACE.md` - Detailed error reporting implementation guide
381
+ 17. `ON_ERRORS.md` - Comprehensive analysis of DSL breakage scenarios and error quality
382
+ 18. `spec/integration/dsl_breakage_spec.rb` - Integration tests for all DSL breakage scenarios
383
+ 19. `spec/integration/potential_breakage_spec.rb` - Edge cases that should break but might not
384
+ 20. `docs/development/README.md` - Development guides directory index
385
+ 21. `docs/development/error-reporting.md` - Comprehensive error reporting standards and patterns
386
+
387
+ #