kumi 0.0.6 → 0.0.7

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 (54) hide show
  1. checksums.yaml +4 -4
  2. data/CLAUDE.md +33 -176
  3. data/README.md +33 -2
  4. data/docs/SYNTAX.md +2 -7
  5. data/docs/features/array-broadcasting.md +1 -1
  6. data/docs/schema_metadata/broadcasts.md +53 -0
  7. data/docs/schema_metadata/cascades.md +45 -0
  8. data/docs/schema_metadata/declarations.md +54 -0
  9. data/docs/schema_metadata/dependencies.md +57 -0
  10. data/docs/schema_metadata/evaluation_order.md +29 -0
  11. data/docs/schema_metadata/examples.md +95 -0
  12. data/docs/schema_metadata/inferred_types.md +46 -0
  13. data/docs/schema_metadata/inputs.md +86 -0
  14. data/docs/schema_metadata.md +108 -0
  15. data/lib/kumi/analyzer/passes/broadcast_detector.rb +52 -57
  16. data/lib/kumi/analyzer/passes/dependency_resolver.rb +8 -8
  17. data/lib/kumi/analyzer/passes/input_collector.rb +2 -2
  18. data/lib/kumi/analyzer/passes/name_indexer.rb +2 -2
  19. data/lib/kumi/analyzer/passes/semantic_constraint_validator.rb +15 -16
  20. data/lib/kumi/analyzer/passes/toposorter.rb +23 -23
  21. data/lib/kumi/analyzer/passes/type_checker.rb +7 -9
  22. data/lib/kumi/analyzer/passes/type_consistency_checker.rb +2 -2
  23. data/lib/kumi/analyzer/passes/type_inferencer.rb +24 -24
  24. data/lib/kumi/analyzer/passes/unsat_detector.rb +11 -13
  25. data/lib/kumi/analyzer.rb +5 -5
  26. data/lib/kumi/compiler.rb +39 -45
  27. data/lib/kumi/error_reporting.rb +1 -1
  28. data/lib/kumi/explain.rb +12 -0
  29. data/lib/kumi/export/node_registry.rb +2 -2
  30. data/lib/kumi/json_schema/generator.rb +63 -0
  31. data/lib/kumi/json_schema/validator.rb +25 -0
  32. data/lib/kumi/json_schema.rb +14 -0
  33. data/lib/kumi/{parser → ruby_parser}/build_context.rb +1 -1
  34. data/lib/kumi/{parser → ruby_parser}/declaration_reference_proxy.rb +3 -3
  35. data/lib/kumi/{parser → ruby_parser}/dsl.rb +1 -1
  36. data/lib/kumi/{parser → ruby_parser}/dsl_cascade_builder.rb +2 -2
  37. data/lib/kumi/{parser → ruby_parser}/expression_converter.rb +14 -14
  38. data/lib/kumi/{parser → ruby_parser}/guard_rails.rb +1 -1
  39. data/lib/kumi/{parser → ruby_parser}/input_builder.rb +1 -1
  40. data/lib/kumi/{parser → ruby_parser}/input_field_proxy.rb +4 -4
  41. data/lib/kumi/{parser → ruby_parser}/input_proxy.rb +1 -1
  42. data/lib/kumi/{parser → ruby_parser}/nested_input.rb +1 -1
  43. data/lib/kumi/{parser → ruby_parser}/parser.rb +11 -10
  44. data/lib/kumi/{parser → ruby_parser}/schema_builder.rb +1 -1
  45. data/lib/kumi/{parser → ruby_parser}/sugar.rb +1 -1
  46. data/lib/kumi/ruby_parser.rb +10 -0
  47. data/lib/kumi/schema.rb +10 -4
  48. data/lib/kumi/schema_instance.rb +6 -6
  49. data/lib/kumi/schema_metadata.rb +524 -0
  50. data/lib/kumi/vectorization_metadata.rb +4 -4
  51. data/lib/kumi/version.rb +1 -1
  52. data/lib/kumi.rb +14 -0
  53. metadata +28 -15
  54. data/lib/generators/trait_engine/templates/schema_spec.rb.erb +0 -27
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 91e6e3b6ce1e4911d37588ba8aaf9b89f8129d23fe93b05268756c417249da90
4
- data.tar.gz: f019de05a9e05957184fc649d187306fa7cd3736cb9d04c56d6080d4a3cde9de
3
+ metadata.gz: ec2c56684edac64e9818bbf85de98e9855c3d50df80c490c8f868b3e9b701dab
4
+ data.tar.gz: d5246f98e10b0365b47f6a67fed5c3a4cbc77d5ad15905d93b046251965135f5
5
5
  SHA512:
6
- metadata.gz: 6d6439258bcb876374c5f7ca3bafa4e59faabf112e3cfe2dac532f752b2b7ef8533bf888c4e6feb1509995069a103a258b37c6b18b0164487e5215e03dd85b10
7
- data.tar.gz: 6e64f9725569836d7a17b83aa82f316f01d4a9169a1323cee3d1d5fcf7d3782902b9c0695bcdb3735a4c206906463a4b7ca3e14f39f253ba23bf23d572ce95aa
6
+ metadata.gz: f71ba6867b72145247b5c1ea4c3b197f831996bf078798c6a9decdb4e047f83859e062e6a6411e2311d279f8a8cc03ca7e16ac194c9a27b84f8a55b67faa3fcb
7
+ data.tar.gz: 70c4dab6bf036da2d507f89c2d8e9d65a24da2685412d3e517a2b3c1696d200c294c512786c85bfccf9feca301e90e70a26999f5ed1528221331b55f77175c8d
data/CLAUDE.md CHANGED
@@ -5,11 +5,9 @@
5
5
  !! Do not care about linter or coverage unless asked to do so.
6
6
  !! IMPORTANT: Communication style - Write direct, factual statements. Avoid promotional language, unnecessary claims, or marketing speak. State what the system does, not what benefits it provides. Use TODOs for missing information rather than placeholder claims.
7
7
 
8
- This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
9
-
10
8
  ## Project Overview
11
9
 
12
- 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.
10
+ Kumi is a Declarative logic and rules engine framework with static analysis for Ruby.
13
11
 
14
12
  ## Development Commands
15
13
 
@@ -18,29 +16,11 @@ Kumi is a declarative decision-modeling compiler for Ruby that transforms comple
18
16
  - `bundle exec rspec spec/path/to/specific_spec.rb` - Run specific test file
19
17
  - `bundle exec rspec spec/path/to/specific_spec.rb:123` - Run specific test at line
20
18
 
21
- ### Linting & Code Quality
22
- - `bundle exec rubocop` - Run RuboCop linter
23
- - `bundle exec rubocop -a` - Auto-fix RuboCop issues where possible
24
- - `rake` - Run default task (includes rspec and rubocop)
25
-
26
19
  ### Gem Management
27
20
  - `bundle install` - Install dependencies
28
21
  - `gem build kumi.gemspec` - Build the gem
29
22
  - `gem install ./kumi-*.gem` - Install locally built gem
30
23
 
31
- ### Kumi CLI
32
- - `./bin/kumi -i` - Start interactive REPL mode for rapid schema testing
33
- - `./bin/kumi -f schema.rb -d data.json` - Execute schema file with input data
34
- - `./bin/kumi -f schema.rb -k key1,key2` - Extract specific keys from schema
35
- - `./bin/kumi -f schema.rb -e key_name` - Explain how a key is computed
36
- - `./bin/kumi -f schema.rb -d data.json -o json` - Output results in JSON format
37
-
38
- **CLI Features**:
39
- - Interactive REPL with schema loading, data manipulation, and live evaluation
40
- - File-based schema execution with JSON/YAML input data support
41
- - Selective key extraction and explain functionality for debugging
42
- - Multiple output formats (pretty, JSON, YAML) for integration
43
-
44
24
  ## Architecture Overview
45
25
 
46
26
  ### Core Components
@@ -50,13 +30,7 @@ Kumi is a declarative decision-modeling compiler for Ruby that transforms comple
50
30
  - Provides the `schema(&block)` DSL method that builds the syntax tree, runs analysis, and compiles to executable form
51
31
  - Generates a `Runner` instance for executing queries against input data
52
32
 
53
- **Parser** (`lib/kumi/parser/`):
54
- - `dsl.rb` - Main DSL parser that converts Ruby block syntax into AST nodes
55
- - `dsl_builder_context.rb` - Context for building DSL elements with input/value/trait methods
56
- - `dsl_cascade_builder.rb` - Specialized builder for cascade expressions
57
- - `dsl_proxy.rb` - Proxy object for method delegation during parsing
58
- - `input_dsl_proxy.rb` - Proxy for input block DSL supporting both `key` method and type-specific DSL methods
59
- - `input_proxy.rb` - Proxy for `input.field_name` references in expressions
33
+ **Parser** (`lib/kumi/ruby_parser{/*,.rb}`):
60
34
 
61
35
  **Syntax Tree** (`lib/kumi/syntax/`):
62
36
  - `node.rb` - Base node class with location tracking
@@ -66,12 +40,13 @@ Kumi is a declarative decision-modeling compiler for Ruby that transforms comple
66
40
  - `input_declaration.rb` - Input field declaration nodes (formerly FieldDecl)
67
41
  - `call_expression.rb` - Function call expression nodes
68
42
  - `array_expression.rb` - Array expression nodes (formerly ListExpression)
69
- - `hash_expression.rb` - Hash expression nodes (for future hash literals)
43
+ - `hash_expression.rb` - Hash expression nodes (for future hash literals) (currently not used)
70
44
  - `cascade_expression.rb` - Cascade expression nodes (conditional values)
71
45
  - `case_expression.rb` - Case expression nodes (formerly WhenCaseExpression)
72
46
  - `literal.rb` - Literal value nodes
73
- - `input_reference.rb` - Input field reference nodes (formerly FieldRef)
74
- - `declaration_reference.rb` - Declaration reference nodes (formerly Binding)
47
+ - `input_reference.rb` - Input field reference nodes (formerly FieldRef)
48
+ - `input_element_reference.rb` - Reference to nested input field (array -> obj.field)
49
+ - `declaration_reference.rb` - Declaration reference value or trait nodes
75
50
 
76
51
  **Analyzer** (`lib/kumi/analyzer.rb`):
77
52
  - Multi-pass analysis system that validates schemas and builds dependency graphs
@@ -135,10 +110,7 @@ end
135
110
  ```
136
111
 
137
112
  **Function Call Syntax**:
138
- - **Symbol style**: `fn(:function_name, arg1, arg2)` - Always works, explicit
139
- - **Method style**: `fn.function_name(arg1, arg2)` - Also works, more readable
140
- - **Incorrect**: `fn()` - Empty function calls cause parse errors
141
- - **Incorrect**: `fn.function_name()` - Empty method calls cause parse errors
113
+ - **Symbol style**: `fn(:function_name, arg1, arg2, ...)` - The only supported function call syntax
142
114
 
143
115
  **Arithmetic Operations**:
144
116
  - **Sugar Syntax**: `input.field1 + input.field2` - Works for input fields and value references
@@ -147,26 +119,13 @@ end
147
119
 
148
120
  **Cascade Condition Syntax**:
149
121
  ```ruby
150
- # CORRECT - use symbols for trait references in cascades
151
122
  value :status do
152
123
  on trait_name, "Result"
153
124
  base "Default"
154
125
  end
155
-
156
- # INCORRECT - bare identifiers don't work in cascade conditions
157
- value :status do
158
- on trait_name, "Result" # This will fail
159
- base "Default"
160
- end
161
126
  ```
162
127
 
163
- **UnsatDetector Considerations**:
164
- - Cascades with mutually exclusive conditions are valid (e.g., `amount < 100` vs `amount >= 100`)
165
- - Values that depend on such cascades are also valid (fixed in recent update)
166
- - Use clear, non-contradictory trait names to avoid confusion
167
-
168
128
  ### Key Patterns
169
-
170
129
  **DSL Structure**:
171
130
  ```ruby
172
131
  schema do
@@ -177,6 +136,14 @@ schema do
177
136
  array :scores, elem: { type: :float }
178
137
  hash :metadata, key: { type: :string }, val: { type: :any }
179
138
 
139
+ array :line_items do
140
+ float :price
141
+ integer :quantity
142
+ string :category
143
+ end
144
+
145
+
146
+
180
147
  # Fields with no declared type
181
148
  any :misc_field
182
149
  end
@@ -191,20 +158,13 @@ end
191
158
  ```
192
159
 
193
160
  **IMPORTANT CASCADE CONDITION SYNTAX:**
194
- In cascade expressions (`value :name do ... end`), trait references use **symbols**, not bare identifiers:
161
+ In cascade expressions (`value :name do ... end`), trait references use bare identifiers:
195
162
  ```ruby
196
163
  value :status do
197
- on adult, "Adult Status" # ✅ Correct - use trait_name symbol
164
+ on adult, "Adult Status"
198
165
  on verified, "Verified User"
199
166
  base "Unverified"
200
167
  end
201
-
202
- # NOT this:
203
- value :status do
204
- on adult, "Adult Status" # ❌ Wrong - don't use bare identifier in cascade
205
- on verified, "Verified User" # ❌ Wrong
206
- base "Unverified"
207
- end
208
168
  ```
209
169
 
210
170
  **Input Block System**:
@@ -260,72 +220,26 @@ The `examples/` directory contains comprehensive examples showing Kumi usage pat
260
220
  - `spec/fixtures/` - Test fixtures and sample schemas
261
221
  - `spec/support/` - Test helpers (`ast_factory.rb`, `schema_generator.rb`)
262
222
 
263
- ## Key Files for Understanding
264
-
265
- 1. `lib/kumi/schema.rb` - Start here to understand the main API
266
- 2. `examples/input_block_typing_showcase.rb` - Comprehensive example of current features
267
- 3. `lib/kumi/analyzer.rb` - Core analysis pipeline with multi-pass system
268
- 4. `lib/kumi/types.rb` - Static type system implementation
269
- 5. `lib/kumi/function_registry.rb` - Available functions and extension patterns
270
- 6. `lib/kumi/analyzer/passes/type_inferencer.rb` - Type inference algorithm
271
- 7. `lib/kumi/analyzer/passes/type_checker.rb` - Type validation with enhanced error messages
272
- 8. `spec/kumi/input_block_spec.rb` - Input block syntax and behavior
273
- 9. `spec/integration/compiler_integration_spec.rb` - End-to-end test examples
274
- 10. `docs/DSL.md` - Concise DSL syntax reference
275
- 11. `docs/AST.md` - AST node types and structure reference
276
- 12. `docs/SYNTAX.md` - Comprehensive sugar vs sugar-free syntax comparison with examples
277
- 13. `lib/kumi/cli.rb` - CLI implementation with REPL and file execution
278
- 14. `examples/simple_tax_schema.rb` - CLI-compatible schema example
279
- 15. `docs/features/analysis-cascade-mutual-exclusion.md` - Cascade mutual exclusion detection feature documentation
280
- 16. `docs/features/array-broadcasting.md` - Array broadcasting and vectorization system documentation
281
-
282
- ## CLI Usage and Best Practices
283
-
284
- ### Schema File Requirements
285
- - **Must use module structure**: `module SchemaName; extend Kumi::Schema; schema do ... end; end`
286
- - **Must have proper require**: `require_relative "../lib/kumi"` at the top
287
- - **Must have input block**: Even empty `input {}` blocks are required
288
- - **Avoid inline definitions**: Don't define schemas directly in methods or blocks
289
-
290
- ### CLI Development Workflow
291
- 1. **Start with REPL**: Use `./bin/kumi -i` for rapid prototyping and testing
292
- 2. **Test with files**: Create `.rb` schema files and `.json/.yaml` data files
293
- 3. **Iterate quickly**: Use `-k key1,key2` to focus on specific outputs
294
- 4. **Debug with explain**: Use `-e key_name` to understand computation flow
295
- 5. **Validate with different data**: Test edge cases with varied input data
296
-
297
- ### Common CLI Patterns
298
- ```bash
299
- # Interactive development
300
- ./bin/kumi -i
301
- kumi> schema examples/my_schema.rb
302
- kumi> data test_data.json
303
- kumi> get result
304
-
305
- # File-based execution
306
- ./bin/kumi -f examples/tax_schema.rb -d examples/tax_data.json -k total_tax,effective_rate
307
-
308
- # Debugging computations
309
- ./bin/kumi -f examples/complex_schema.rb -d examples/data.json -e complex_calculation
310
-
311
- # Output formats for integration
312
- ./bin/kumi -f schema.rb -d data.json -k results -o json | jq '.results'
313
- ```
223
+ ## Files for Understanding
224
+
225
+ . `docs/*` - Documents about Kumi, its features, DSL syntax, ...
226
+ - `examples/*` Random examples of very diverse contexts.
314
227
 
315
228
  ### Troubleshooting Schema Issues
316
229
  - **Parse Errors**: Check function syntax (avoid empty `fn()` calls)
317
- - **Module Not Found**: Ensure proper module structure and naming
318
- - **UnsatDetector Errors**: Review trait logic for contradictions
319
- - **Type Errors**: Check input block type declarations match usage
320
- - **Runtime Errors**: Use explain to trace computation dependencies
230
+ - **Module Not Found**: Ensure proper module structure and naming, see examples
231
+ - **UnsatDetector Errors**: Review trait logic for contradictions, add debugs!
232
+ - **Type Errors**: Check input block type declarations match usage, add debugs!
233
+ - **Runtime Errors**: Use explain to trace computation dependencies, add debugs!
321
234
 
322
235
  ## Input Block System Details
323
236
 
324
237
  ### Required Input Blocks
325
- - **All schemas must have an input block** - This is now mandatory
238
+ - **All schemas must have an input block** -
326
239
  - Input blocks declare expected fields with optional type and domain constraints
327
- - **Empty input blocks are allowed** - Use `input {}` for schemas that don't require external data
328
- - Fields are accessed via `input.field_name` syntax (replaces deprecated `key(:field)`)
240
+ - **Empty input blocks are allowed** -`input {}` Even if its not very useful.
241
+ - Fields are accessed via `input.field_name` or `input.field.nested_field.nested_nested_field` which
242
+ works for referencing nested array input declarations.
329
243
 
330
244
  ### Type System Integration
331
245
  - **Declared Types**: Explicit type declarations in input blocks (e.g. `integer :field`, `string :name`, `any :field`)
@@ -335,26 +249,21 @@ kumi> get result
335
249
  - **Helper Functions**: Use `array(:type)` and `hash(:key_type, :value_type)` for complex types
336
250
 
337
251
  ### Parser Components
338
- - `input_dsl_proxy.rb` - Supports type-specific DSL methods (`integer`, `float`, `string`, `boolean`, `array`, `hash`, `any`)
339
- - `input_proxy.rb` - Handles `input.field_name` references in expressions
340
- - `input_collector.rb` - Collects and validates field metadata consistency
252
+ See `lib/kumi/ruby_parser/parser.rb`
341
253
 
342
254
  ### Domain Constraints
343
255
  - Can be declared: `integer :age, domain: 18..65`
344
- - **Implemented**: Domain validation is active and enforced at runtime
345
256
  - Supports Range domains (`18..65`), Array domains (`%w[active inactive]`), and Proc domains for custom validation
346
- - Field metadata includes domain information and runtime validation occurs during `Schema.from()`
347
-
257
+ - Analyzer do some limited domain UNSAT detection, and its used to validated against input at Runtime
348
258
  ### Type Examples
349
259
  ```ruby
350
260
  input do
351
- # New type-specific DSL methods (recommended)
352
261
  string :name
353
262
  integer :age, domain: 18..65
354
263
  hash :metadata, key: { type: :string }, val: { type: :any }
355
264
 
356
- # For untyped/any fields
357
- any :misc
265
+ #generic type
266
+ any :misc # this will make Kumi lose most of its analyze/inference power
358
267
  end
359
268
  ```
360
269
 
@@ -437,59 +346,20 @@ trait :qualified, input.age, :>=, 21, input.score # OLD - shows deprecation war
437
346
  3. Add pass to `PASSES` array in `lib/kumi/analyzer.rb` in correct order
438
347
  4. Consider dependencies on other passes (e.g., TypeChecker needs TypeInferencer)
439
348
 
440
- ### Working with AST Nodes
441
- - All nodes include `Node` module for location tracking
442
- - Use `spec/support/ast_factory.rb` helpers in tests
443
- - Field declarations use `FieldDecl` nodes with name, domain, and type
444
- - Field references use `FieldRef` nodes (from `input.field_name`) with operator methods
445
- - FieldRef operator methods (>=, <=, >, <, ==, !=) create CallExpression nodes
446
- - CallExpression `&` method enables logical AND chaining
447
-
448
- ### Testing Input Block Features
449
- - See `spec/kumi/input_block_spec.rb` for comprehensive input block tests
450
- - Use `schema_generator.rb` helper for creating test schemas
451
- - All integration tests now require input blocks
452
-
453
349
  ## Architecture Design Principles
454
350
 
455
351
  - **Multi-pass Analysis**: Each analysis pass has a single responsibility and builds on previous passes
456
352
  - **Immutable Syntax Tree**: AST nodes are immutable; analysis results stored separately in analyzer state
457
353
  - **Dependency-driven Evaluation**: All computation follows dependency graph to ensure correct order
458
354
  - **Type Safety**: Optional but comprehensive type checking without breaking existing schemas
459
- - **Backward Compatibility**: New features maintain compatibility with existing DSL and APIs
460
355
  - **Ruby Integration**: Leverages Ruby's metaprogramming while providing structured analysis
461
- - **Separation of Concerns**: Input metadata (types, domains) separated from business logic
462
- - **Class Decomposition**: Large classes split into focused, single-responsibility components following RuboCop guidelines
463
- - **Delegation Pattern**: Complex operations delegated to specialized analyzer and formatter classes
464
356
  - **Unified Error Reporting**: Consistent, localized error messages throughout the system with clear interface patterns
465
357
 
466
358
  ## Code Organization Patterns
467
359
 
468
- ### Modular Validation Architecture
469
- - **Coordinator Classes**: Main classes like `Input::Validator` and `Domain::Validator` coordinate but delegate complex logic
470
- - **Specialized Analyzers**: Domain-specific classes like `RangeAnalyzer` and `EnumAnalyzer` handle specific constraint types
471
- - **Formatter Classes**: Dedicated classes like `ViolationFormatter` handle message formatting with consistent patterns
472
- - **Creator Classes**: Classes like `ViolationCreator` centralize object creation with standardized structure
473
-
474
360
  ### Testing Best Practices
475
361
  - **Spec Organization**: Tests organized by component with clear separation between unit and integration tests
476
362
  - **Error Variable Extraction**: RSpec patterns avoid multiline block chains by extracting error variables for assertion
477
- - **Shared Contexts**: Use `schema_generator` and other shared contexts for consistent test setup
478
-
479
- ### RuboCop Compliance
480
- - **Method Length**: Keep methods under 10 lines through extraction and delegation
481
- - **Class Length**: Break classes over 100 lines into focused components
482
- - **Complexity Metrics**: Reduce cyclomatic and ABC complexity through single-responsibility design
483
- - **Style Consistency**: Follow Ruby style guidelines for readability and maintainability
484
-
485
- ### Error Reporting Architecture
486
- - **Unified Interface**: Use `ErrorReporter` module and `ErrorReporting` mixin for consistent error handling
487
- - **Location Information**: All errors must include proper file:line:column location data
488
- - **Precise Location Tracking**: Error objects preserve location data in `.location` attribute for programmatic access
489
- - **User Code Location**: Errors point to actual user DSL code, not internal library files
490
- - **Backward Compatibility**: Support both legacy `[location, message]` and new `ErrorEntry` formats
491
- - **Type Categorization**: Errors categorized as `:syntax`, `:semantic`, `:type`, `:runtime`
492
- - **Enhanced Messaging**: Support for error suggestions, context, and similar name detection
493
363
 
494
364
  ## Development Guides and Standards
495
365
 
@@ -522,18 +392,5 @@ end
522
392
  - Use `spec/integration/dsl_breakage_spec.rb` patterns for comprehensive error testing
523
393
  - Use `spec/integration/potential_breakage_spec.rb` for edge cases break
524
394
  - Use `spec/fixtures/location_tracking_test_schema.rb` fixture for testing different syntax error types
525
- - Test backward compatibility with existing analyzer pass specs
526
-
527
- ### Key Development Files
528
- 12. `lib/kumi/error_reporter.rb` - Central error reporting functionality
529
- 13. `lib/kumi/error_reporting.rb` - Mixin for consistent error interfaces
530
- 14. `spec/integration/location_tracking_spec.rb` - Comprehensive tests for error location accuracy
531
- 15. `spec/fixtures/location_tracking_test_schema.rb` - Fixture with intentional syntax errors for location testing
532
- 16. `ERROR_REPORTING_INTERFACE.md` - Detailed error reporting implementation guide
533
- 17. `ON_ERRORS.md` - Comprehensive analysis of DSL breakage scenarios and error quality
534
- 18. `spec/integration/dsl_breakage_spec.rb` - Integration tests for all DSL breakage scenarios
535
- 19. `spec/integration/potential_breakage_spec.rb` - Edge cases that should break but might not
536
- 20. `docs/development/README.md` - Development guides directory index
537
- 21. `docs/development/error-reporting.md` - Comprehensive error reporting standards and patterns
538
395
 
539
396
  #
data/README.md CHANGED
@@ -3,7 +3,7 @@
3
3
  [![CI](https://github.com/amuta/kumi/workflows/CI/badge.svg)](https://github.com/amuta/kumi/actions)
4
4
  [![Gem Version](https://badge.fury.io/rb/kumi.svg)](https://badge.fury.io/rb/kumi)
5
5
 
6
- Kumi is a Declarative logic framework with static analysis for Ruby.
6
+ Kumi is a Declarative logic and rules engine framework with static analysis for Ruby.
7
7
 
8
8
  It is well-suited for scenarios with complex, interdependent calculations, enforcing validation and consistency across your business rules while maintaining performance.
9
9
 
@@ -330,6 +330,37 @@ Kumi::Explain.call(FederalTax2024, :fed_tax, inputs: {income: 100_000, filing_st
330
330
 
331
331
  </details>
332
332
 
333
+ <details>
334
+ <summary><strong>📋 Schema Metadata</strong> - Extract structured information for tooling</summary>
335
+
336
+ ### Schema Metadata
337
+
338
+ Access structured metadata for building tools like form generators and dependency analyzers:
339
+
340
+ ```ruby
341
+ metadata = FederalTax2024.schema_metadata
342
+
343
+ # Processed metadata (tool-friendly)
344
+ metadata.inputs # Input field types and domains
345
+ metadata.values # Value declarations with dependencies
346
+ metadata.traits # Trait conditions and metadata
347
+ metadata.functions # Function registry information
348
+
349
+ # Raw analyzer state (advanced usage)
350
+ metadata.dependencies # Dependency graph between declarations
351
+ metadata.evaluation_order # Topologically sorted computation order
352
+ metadata.inferred_types # Type inference results
353
+ metadata.declarations # Raw AST declaration nodes
354
+
355
+ # Export formats
356
+ metadata.to_h # Serializable hash for JSON/APIs
357
+ metadata.to_json_schema # JSON Schema for input validation
358
+ ```
359
+
360
+ The SchemaMetadata interface provides both processed metadata for tool development and raw analyzer state for advanced use cases. Complete documentation available in the SchemaMetadata class and [docs/schema_metadata.md](docs/schema_metadata.md).
361
+
362
+ </details>
363
+
333
364
  ## Usage
334
365
 
335
366
  **Suitable for:**
@@ -364,4 +395,4 @@ Bug reports and pull requests are welcome on GitHub at https://github.com/amuta/
364
395
 
365
396
  ## License
366
397
 
367
- MIT License. See [LICENSE](LICENSE).
398
+ MIT License. See [LICENSE](LICENSE).
data/docs/SYNTAX.md CHANGED
@@ -131,13 +131,8 @@ trait :needs_review, fn(:and, needs_improvement, fn(:>, input.attempts, 2))
131
131
  ### String Operations
132
132
 
133
133
  ```ruby
134
- # With Sugar
135
- trait :long_name, input.name.length > 20
136
- trait :starts_with_a, input.name.start_with?("A")
137
- trait :contains_space, input.name.include?(" ")
138
-
139
- # Sugar-Free
140
- trait :long_name, fn(:>, fn(:string_length, input.name), 20)
134
+ # All string operations use function syntax
135
+ trait :long_name, fn(:string_length, input.name) > 20
141
136
  trait :starts_with_a, fn(:start_with?, input.name, "A")
142
137
  trait :contains_space, fn(:contains?, input.name, " ")
143
138
  ```
@@ -24,7 +24,7 @@ schema do
24
24
  integer :quantity
25
25
  string :category
26
26
  end
27
- scalar :tax_rate, type: :float
27
+ float :tax_rate, type: :float
28
28
  end
29
29
 
30
30
  # Element-wise computation - broadcasts over each item
@@ -0,0 +1,53 @@
1
+ # Broadcasts Metadata
2
+
3
+ Array broadcasting operation analysis for vectorized computations.
4
+
5
+ ## Structure
6
+
7
+ ```ruby
8
+ state[:broadcasts] = {
9
+ array_fields: Hash,
10
+ vectorized_operations: Hash,
11
+ reduction_operations: Hash
12
+ }
13
+ ```
14
+
15
+ ## Array Fields
16
+
17
+ ```ruby
18
+ array_fields: {
19
+ :line_items => {
20
+ element_fields: [:price, :quantity, :name],
21
+ element_types: { price: :float, quantity: :integer, name: :string }
22
+ }
23
+ }
24
+ ```
25
+
26
+ ## Vectorized Operations
27
+
28
+ ```ruby
29
+ vectorized_operations: {
30
+ :item_totals => {
31
+ operation: :multiply,
32
+ vectorized_args: { 0 => true, 1 => true }
33
+ }
34
+ }
35
+ ```
36
+
37
+ ## Reduction Operations
38
+
39
+ ```ruby
40
+ reduction_operations: {
41
+ :total_amount => {
42
+ function: :sum,
43
+ source: :array_field
44
+ }
45
+ }
46
+ ```
47
+
48
+ ## Usage
49
+
50
+ - Compiler optimizations
51
+ - Parallel execution
52
+ - Type inference
53
+ - Performance analysis
@@ -0,0 +1,45 @@
1
+ # Cascades Metadata
2
+
3
+ Cascade mutual exclusion analysis for safe conditional cycles.
4
+
5
+ ## Structure
6
+
7
+ ```ruby
8
+ state[:cascades] = {
9
+ cascade_name => {
10
+ condition_traits: Array,
11
+ condition_count: Integer,
12
+ all_mutually_exclusive: Boolean,
13
+ exclusive_pairs: Integer,
14
+ total_pairs: Integer
15
+ }
16
+ }
17
+ ```
18
+
19
+ ## Example
20
+
21
+ ```ruby
22
+ {
23
+ :tax_rate => {
24
+ condition_traits: [:single, :married],
25
+ condition_count: 2,
26
+ all_mutually_exclusive: true,
27
+ exclusive_pairs: 1,
28
+ total_pairs: 1
29
+ }
30
+ }
31
+ ```
32
+
33
+ ## Fields
34
+
35
+ - `condition_traits`: Trait names used in cascade conditions
36
+ - `all_mutually_exclusive`: Whether all condition pairs are exclusive
37
+ - `exclusive_pairs`: Count of mutually exclusive pairs
38
+ - `total_pairs`: Total possible pairs
39
+
40
+ ## Usage
41
+
42
+ - Cycle safety analysis
43
+ - Topological sorting
44
+ - Optimization detection
45
+ - Dependency validation
@@ -0,0 +1,54 @@
1
+ # Declarations Metadata
2
+
3
+ Processed declaration metadata for all schema declarations (traits and values) with clean, serializable information.
4
+
5
+ ## Access
6
+
7
+ ```ruby
8
+ metadata = MySchema.schema_metadata
9
+ declarations = metadata.declarations
10
+ ```
11
+
12
+ ## Structure
13
+
14
+ ```ruby
15
+ # Returns Hash<Symbol, Hash>
16
+ {
17
+ declaration_name => {
18
+ type: :trait | :value, # Declaration type
19
+ expression: String # Human-readable expression
20
+ }
21
+ }
22
+ ```
23
+
24
+ ## Example
25
+
26
+ ```ruby
27
+ metadata.declarations
28
+ # => {
29
+ # :adult => { type: :trait, expression: ">=(input.age, 18)" },
30
+ # :tax_amount => { type: :value, expression: "multiply(input.income, tax_rate)" },
31
+ # :status => { type: :value, expression: "cascade" }
32
+ # }
33
+ ```
34
+
35
+ ## Raw AST Access
36
+
37
+ For advanced use cases requiring direct AST manipulation:
38
+
39
+ ```ruby
40
+ raw_declarations = metadata.analyzer_state[:declarations]
41
+ # => { :adult => #<TraitDeclaration...>, :tax_amount => #<ValueDeclaration...> }
42
+ ```
43
+
44
+ ## AST Node Types
45
+
46
+ - **TraitDeclaration**: Boolean conditions
47
+ - **ValueDeclaration**: Computed values or cascades
48
+
49
+ ## Usage
50
+
51
+ - Dependency analysis
52
+ - Code generation
53
+ - AST traversal
54
+ - Type inference
@@ -0,0 +1,57 @@
1
+ # Dependencies Metadata
2
+
3
+ Processed dependency information showing relationships between declarations with clean, serializable data.
4
+
5
+ ## Access
6
+
7
+ ```ruby
8
+ metadata = MySchema.schema_metadata
9
+ dependencies = metadata.dependencies
10
+ ```
11
+
12
+ ## Structure
13
+
14
+ ```ruby
15
+ # Returns Hash<Symbol, Array<Hash>>
16
+ {
17
+ declaration_name => [
18
+ {
19
+ to: Symbol, # Target declaration name
20
+ conditional: Boolean, # True if dependency is conditional (cascade branch)
21
+ cascade_owner: Symbol # Optional: cascade that owns this conditional edge
22
+ }
23
+ ]
24
+ }
25
+ ```
26
+
27
+ ## Example
28
+
29
+ ```ruby
30
+ metadata.dependencies
31
+ # => {
32
+ # :tax_amount => [
33
+ # { to: :income, conditional: false },
34
+ # { to: :deductions, conditional: false }
35
+ # ],
36
+ # :status => [
37
+ # { to: :adult, conditional: true, cascade_owner: :status },
38
+ # { to: :verified, conditional: true, cascade_owner: :status }
39
+ # ]
40
+ # }
41
+ ```
42
+
43
+ ## Raw Edge Objects
44
+
45
+ For advanced use cases requiring direct Edge object access:
46
+
47
+ ```ruby
48
+ raw_dependencies = metadata.analyzer_state[:dependencies]
49
+ # => { :tax_amount => [#<Edge to: :income>, #<Edge to: :deductions>] }
50
+ ```
51
+
52
+ ## Usage
53
+
54
+ - Topological sorting
55
+ - Cycle detection
56
+ - Evaluation planning
57
+ - Dependency visualization
@@ -0,0 +1,29 @@
1
+ # Evaluation Order Metadata
2
+
3
+ Topologically sorted order for safe declaration evaluation.
4
+
5
+ ## Structure
6
+
7
+ ```ruby
8
+ state[:evaluation_order] = [:name1, :name2, :name3, ...]
9
+ ```
10
+
11
+ ## Example
12
+
13
+ ```ruby
14
+ [:income, :deductions, :taxable_income, :tax_rate, :tax_amount, :adult, :status]
15
+ ```
16
+
17
+ ## Properties
18
+
19
+ - Dependencies appear before dependents
20
+ - Handles conditional cycles in cascades
21
+ - Deterministic ordering
22
+ - Leaf nodes typically appear first
23
+
24
+ ## Usage
25
+
26
+ - Compilation order
27
+ - Evaluation sequencing
28
+ - Optimization planning
29
+ - Parallel execution grouping