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 +4 -4
- data/CHANGELOG.md +15 -0
- data/CLAUDE.md +1 -1
- data/CODEOWNERS +29 -0
- data/README.md +1 -1
- data/lib/legion/settings/agent_loader.rb +13 -1
- data/lib/legion/settings/dns_bootstrap.rb +14 -1
- data/lib/legion/settings/loader.rb +22 -15
- data/lib/legion/settings/version.rb +1 -1
- data/lib/legion/settings.rb +10 -2
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: aa9a361cc8abaac426787e16814ad39859d0fd7d0690f0ca0025a3aeb626fd80
|
|
4
|
+
data.tar.gz: 33f4085cb92a849f779a0dd867436bedcb4a3970ba430f9739c3d4014db314ec
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
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.
|
|
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
|
+
**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:
|
|
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:
|
|
61
|
-
gaia:
|
|
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:
|
|
70
|
-
reserved_words:
|
|
71
|
-
agentic:
|
|
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
|
|
192
|
-
|
|
193
|
-
|
|
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
|
-
|
|
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
|
data/lib/legion/settings.rb
CHANGED
|
@@ -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
|
-
|
|
92
|
+
if errors.empty?
|
|
93
|
+
logger.info('Settings validation passed')
|
|
94
|
+
return
|
|
95
|
+
end
|
|
92
96
|
|
|
93
|
-
|
|
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
|