legion-settings 1.3.9 → 1.3.11

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c0fcaa25c5784c19c1c6af9e6b566eccd3a955ae8701a09e20b9c628b7bfa2fd
4
- data.tar.gz: d2c376b14cae93615e734267a29336e689327078195dd604ed7bf3c3c8e981b0
3
+ metadata.gz: aa9a361cc8abaac426787e16814ad39859d0fd7d0690f0ca0025a3aeb626fd80
4
+ data.tar.gz: 33f4085cb92a849f779a0dd867436bedcb4a3970ba430f9739c3d4014db314ec
5
5
  SHA512:
6
- metadata.gz: 143dab0104ef8757c0768832f6cba3494e0d32fadf7deb213d69e06bc89c8de12b7203db3448fef5181e022c671fc23cf6876fdf9e4a36f4e55dc2ce24ae81fc
7
- data.tar.gz: '0879c1aff38d66f3decedc96f0f8b0efdb38939a62a5ed71de2085c614f4e8e1da61740bfb03ad1c7cc88d4e92eca8ea4fa8493447adef07fdf2d213749c2751'
6
+ metadata.gz: f838ac6025e9a63d736e879df9956960ee4b6638c09811a046ac5698769215ae2f97085da3e2a49054588869e8c7565649c49026ce9cb0538a066369c5872776
7
+ data.tar.gz: 768f206060c3b23f78097222d919d14d613991f04ba1bc1efdb07faeb480bbdb7f85200ed90d60158b18b71b79a953a77b1c0c46060a7a33857fc06addc90f34
data/CHANGELOG.md CHANGED
@@ -1,5 +1,20 @@
1
1
  # Legion::Settings Changelog
2
2
 
3
+ ## [1.3.11] - 2026-03-22
4
+
5
+ ### Added
6
+ - `loader.rb`: debug logging on `load_directory` (file count), `load_module_settings`, and `load_module_default` (module name)
7
+ - `loader.rb`: warn logging in `start_dns_background_refresh`, `read_resolv_config`, and `detect_fqdn` rescue blocks
8
+ - `settings.rb`: info logging on successful load (file count), validate! success, and debug on resolve_secrets! completion
9
+ - `settings.rb`: warn logging before raising `ValidationError` in production mode
10
+ - `dns_bootstrap.rb`: warn on HTTP fetch failure, debug on cache hit, warn when corrupt cache is deleted
11
+ - `agent_loader.rb`: warn on file parse failure, debug on agent loaded
12
+
13
+ ## [1.3.10] - 2026-03-22
14
+
15
+ ### Added
16
+ - `extensions.parallel_pool_size` setting (default: 24) to control thread pool size for parallel extension loading
17
+
3
18
  ## [1.3.9] - 2026-03-21
4
19
 
5
20
  ### Added
data/CLAUDE.md CHANGED
@@ -8,7 +8,7 @@
8
8
  Hash-like configuration store for the LegionIO framework. Loads settings from JSON files, directories, and environment variables. Provides a unified `Legion::Settings[:key]` accessor used by all other Legion gems. Includes schema-based validation with type inference, enum constraints, and cross-module checks.
9
9
 
10
10
  **GitHub**: https://github.com/LegionIO/legion-settings
11
- **Version**: 1.3.5
11
+ **Version**: 1.3.9
12
12
  **License**: Apache-2.0
13
13
 
14
14
  ## Architecture
data/CODEOWNERS CHANGED
@@ -1 +1,30 @@
1
+ # Default owner — all files
1
2
  * @Esity
3
+
4
+ # Core library code
5
+ # lib/ @Esity @future-core-team
6
+
7
+ # Loader (file/env/directory loading, deep merge)
8
+ # lib/legion/settings/loader.rb @Esity @future-core-team
9
+
10
+ # Schema validation
11
+ # lib/legion/settings/schema.rb @Esity @future-core-team
12
+ # lib/legion/settings/validation_error.rb @Esity @future-core-team
13
+
14
+ # Secret resolver (vault://, env://, lease://)
15
+ # lib/legion/settings/resolver.rb @Esity @future-security-team
16
+
17
+ # DNS bootstrap
18
+ # lib/legion/settings/dns_bootstrap.rb @Esity @future-infra-team
19
+
20
+ # Agent loader (role-based profile filtering)
21
+ # lib/legion/settings/agent_loader.rb @Esity @future-core-team
22
+
23
+ # Specs
24
+ # spec/ @Esity @future-contributors
25
+
26
+ # Documentation
27
+ # *.md @Esity @future-docs-team
28
+
29
+ # CI/CD
30
+ # .github/ @Esity
data/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Configuration management module for the [LegionIO](https://github.com/LegionIO/LegionIO) framework. Loads settings from JSON files, directories, and environment variables. Provides a unified `Legion::Settings[:key]` accessor used by all other Legion gems.
4
4
 
5
- **Version**: 1.3.5
5
+ **Version**: 1.3.9
6
6
 
7
7
  ## Installation
8
8
 
@@ -17,6 +17,7 @@ module Legion
17
17
  definition = load_file(path)
18
18
  next unless definition && valid?(definition)
19
19
 
20
+ log_debug("Agent loaded: #{definition[:name]} (#{path})")
20
21
  definition.merge(_source_path: path, _source_mtime: File.mtime(path))
21
22
  end
22
23
  end
@@ -27,7 +28,8 @@ module Legion
27
28
  when '.yaml', '.yml' then YAML.safe_load(content, symbolize_names: true)
28
29
  when '.json' then ::JSON.parse(content, symbolize_names: true)
29
30
  end
30
- rescue StandardError
31
+ rescue StandardError => e
32
+ log_warn("Failed to parse agent file #{path}: #{e.message}")
31
33
  nil
32
34
  end
33
35
 
@@ -39,6 +41,16 @@ module Legion
39
41
 
40
42
  true
41
43
  end
44
+
45
+ private
46
+
47
+ def log_debug(message)
48
+ Legion::Logging.debug(message) if defined?(Legion::Logging)
49
+ end
50
+
51
+ def log_warn(message)
52
+ defined?(Legion::Logging) ? Legion::Logging.warn(message) : warn(message)
53
+ end
42
54
  end
43
55
  end
44
56
  end
@@ -43,7 +43,8 @@ module Legion
43
43
  return nil unless response.is_a?(Net::HTTPSuccess)
44
44
 
45
45
  ::JSON.parse(response.body, symbolize_names: true)
46
- rescue StandardError
46
+ rescue StandardError => e
47
+ log_warn("DNS bootstrap fetch failed for #{@url}: #{e.message}")
47
48
  nil
48
49
  end
49
50
 
@@ -65,9 +66,11 @@ module Legion
65
66
  return nil unless File.exist?(@cache_path)
66
67
 
67
68
  raw = ::JSON.parse(File.read(@cache_path), symbolize_names: true)
69
+ log_debug("DNS bootstrap cache hit: #{@cache_path}")
68
70
  raw.delete(:_dns_bootstrap_meta)
69
71
  raw
70
72
  rescue ::JSON::ParserError
73
+ log_warn("DNS bootstrap cache corrupt, deleting: #{@cache_path}")
71
74
  FileUtils.rm_f(@cache_path)
72
75
  nil
73
76
  end
@@ -75,6 +78,16 @@ module Legion
75
78
  def cache_exists?
76
79
  File.exist?(@cache_path)
77
80
  end
81
+
82
+ private
83
+
84
+ def log_debug(message)
85
+ Legion::Logging.debug(message) if defined?(Legion::Logging)
86
+ end
87
+
88
+ def log_warn(message)
89
+ defined?(Legion::Logging) ? Legion::Logging.warn(message) : warn(message)
90
+ end
78
91
  end
79
92
  end
80
93
  end
@@ -52,23 +52,24 @@ module Legion
52
52
  },
53
53
  cache: { enabled: true, connected: false, driver: 'dalli' },
54
54
  extensions: {
55
- core: %w[
55
+ core: %w[
56
56
  lex-node lex-tasker lex-scheduler lex-health lex-ping
57
57
  lex-telemetry lex-metering lex-log lex-audit
58
58
  lex-conditioner lex-transformer lex-exec lex-lex lex-codegen
59
59
  ],
60
- ai: %w[lex-claude lex-openai lex-gemini],
61
- gaia: %w[lex-tick lex-mesh lex-apollo lex-cortex],
62
- categories: {
60
+ ai: %w[lex-claude lex-openai lex-gemini],
61
+ gaia: %w[lex-tick lex-mesh lex-apollo lex-cortex],
62
+ categories: {
63
63
  core: { type: :list, tier: 1 },
64
64
  ai: { type: :list, tier: 2 },
65
65
  gaia: { type: :list, tier: 3 },
66
66
  agentic: { type: :prefix, tier: 4 }
67
67
  },
68
- blocked: [],
69
- reserved_prefixes: %w[core ai agentic gaia],
70
- reserved_words: %w[transport cache crypt data settings json logging llm rbac legion],
71
- agentic: { allowed: nil, blocked: [] }
68
+ blocked: [],
69
+ reserved_prefixes: %w[core ai agentic gaia],
70
+ reserved_words: %w[transport cache crypt data settings json logging llm rbac legion],
71
+ agentic: { allowed: nil, blocked: [] },
72
+ parallel_pool_size: 24
72
73
  },
73
74
  reload: false,
74
75
  reloading: false,
@@ -156,10 +157,14 @@ module Legion
156
157
  end
157
158
 
158
159
  def load_module_settings(config)
160
+ mod_name = config.keys.first
161
+ log_debug("Loading module settings: #{mod_name}")
159
162
  @settings = deep_merge(config, @settings)
160
163
  end
161
164
 
162
165
  def load_module_default(config)
166
+ mod_name = config.keys.first
167
+ log_debug("Loading module defaults: #{mod_name}")
163
168
  merged = deep_merge(@settings, config)
164
169
  deep_diff(@settings, merged) unless @loaded_files.empty?
165
170
  @settings = merged
@@ -188,9 +193,9 @@ module Legion
188
193
  def load_directory(directory)
189
194
  path = directory.gsub(/\\(?=\S)/, '/')
190
195
  if File.readable?(path) && File.executable?(path)
191
- Dir.glob(File.join(path, '**{,/*/**}/*.json')).uniq.each do |file|
192
- load_file(file)
193
- end
196
+ files = Dir.glob(File.join(path, '**{,/*/**}/*.json')).uniq
197
+ files.each { |file| load_file(file) }
198
+ log_debug("Loaded directory #{path}: #{files.size} files")
194
199
  else
195
200
  load_error('insufficient permissions for loading', directory: directory)
196
201
  end
@@ -251,8 +256,8 @@ module Legion
251
256
  Thread.new do
252
257
  fresh = bootstrap.fetch
253
258
  bootstrap.write_cache(fresh) if fresh
254
- rescue StandardError
255
- # Background refresh is best-effort
259
+ rescue StandardError => e
260
+ log_warn("DNS background refresh failed: #{e.message}")
256
261
  end
257
262
  end
258
263
 
@@ -399,7 +404,8 @@ module Legion
399
404
  search_domains: config[:search]&.map(&:to_s)&.uniq,
400
405
  nameservers: config[:nameserver]&.map(&:to_s)&.uniq
401
406
  }
402
- rescue StandardError
407
+ rescue StandardError => e
408
+ log_warn("Failed to read resolv config: #{e.message}")
403
409
  { search_domains: [], nameservers: [] }
404
410
  end
405
411
 
@@ -408,7 +414,8 @@ module Legion
408
414
  return nil if fqdn.nil?
409
415
 
410
416
  fqdn.include?('.') ? fqdn : nil
411
- rescue StandardError
417
+ rescue StandardError => e
418
+ log_warn("Failed to detect FQDN: #{e.message}")
412
419
  nil
413
420
  end
414
421
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Legion
4
4
  module Settings
5
- VERSION = '1.3.9'
5
+ VERSION = '1.3.11'
6
6
  end
7
7
  end
@@ -23,6 +23,7 @@ module Legion
23
23
  options[:config_dirs]&.each do |directory|
24
24
  @loader.load_directory(directory)
25
25
  end
26
+ logger.info("Settings loaded from #{@loader.loaded_files.size} files")
26
27
  @loader
27
28
  end
28
29
 
@@ -88,9 +89,15 @@ module Legion
88
89
  revalidate_all_modules
89
90
  run_cross_validations
90
91
  detect_unknown_keys
91
- return if errors.empty?
92
+ if errors.empty?
93
+ logger.info('Settings validation passed')
94
+ return
95
+ end
92
96
 
93
- raise ValidationError, errors unless dev_mode?
97
+ unless dev_mode?
98
+ logger.warn("Settings validation failed with #{errors.size} error(s)")
99
+ raise ValidationError, errors
100
+ end
94
101
 
95
102
  warn_validation_errors(errors)
96
103
  end
@@ -99,6 +106,7 @@ module Legion
99
106
  @loader = load if @loader.nil?
100
107
  require 'legion/settings/resolver'
101
108
  Resolver.resolve_secrets!(@loader.to_hash)
109
+ logger.debug('Secret resolution complete')
102
110
  end
103
111
 
104
112
  def schema
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: legion-settings
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.9
4
+ version: 1.3.11
5
5
  platform: ruby
6
6
  authors:
7
7
  - Esity