Module: Legion::Extensions::Llm::Inventory::Identity
- Defined in:
- lib/legion/extensions/llm/inventory/identity.rb
Overview
Canonical field normalization plus the ONE 5-tuple lane-id composer.
The lane id is tier:provider_family:instance_id:type:model, composed
here and ONLY here (G22). Every surface that needs an id calls
compose_lane_id; validation is shape/parse checks against Taxonomies
(R1 boundary contract — it enforces the shape the code produces).
The code produces ONLY 5-tuples; nothing else is guarded against.
Defined Under Namespace
Classes: InstanceKey
Class Method Summary collapse
-
.compose_lane_id(tier:, provider_family:, instance_id:, type:, model:) ⇒ Object
The ONE 5-tuple composer (G22): byte-identical to the v0.6.16 ScopedRefresher.compose_id.
-
.instance_id(config) ⇒ Object
M6: the ONE config→instance-id derivation (R6 owner law).
- .normalize_enum(value:, field:, allowed:) ⇒ Object
- .normalize_text(value:, field:) ⇒ Object
-
.parse_lane_id(id) ⇒ Object
Bounded parse: split(':', 5) — the 5th part keeps its colons, which is load-bearing: model names contain ':' (Ollama model:tag, Bedrock model ids).
-
.validate_lane_id!(value:) ⇒ Object
Shape validation (R1 boundary contract): exactly 5 parts (bounded split — the model keeps its colons), part 1 in TIERS, part 4 in TYPES, parts 2/3/5 nonempty NFC.
Class Method Details
.compose_lane_id(tier:, provider_family:, instance_id:, type:, model:) ⇒ Object
The ONE 5-tuple composer (G22): byte-identical to the v0.6.16 ScopedRefresher.compose_id. A pure join of the five identity fields — no normalization here; the fields are normalized by their owners (TIERS/TYPES symbols, InstanceKey, normalize_text) before composing.
48 49 50 |
# File 'lib/legion/extensions/llm/inventory/identity.rb', line 48 def compose_lane_id(tier:, provider_family:, instance_id:, type:, model:) "#{tier}:#{provider_family}:#{instance_id}:#{type}:#{model}" end |
.instance_id(config) ⇒ Object
M6: the ONE config→instance-id derivation (R6 owner law). Instance identity is the operator's CONFIG NAME from the provider config; when the operator configured no instance name, "default" is the ordinary label (no reserved values — see InstanceKey). Consumers CARRY this derivation; they never mint a local variant (node canonical names, family fallbacks, and read-time synthesis are deleted).
97 98 99 100 101 |
# File 'lib/legion/extensions/llm/inventory/identity.rb', line 97 def instance_id(config) return config.instance_id.to_s if config.respond_to?(:instance_id) && config.instance_id 'default' end |
.normalize_enum(value:, field:, allowed:) ⇒ Object
32 33 34 35 36 37 38 39 40 41 42 |
# File 'lib/legion/extensions/llm/inventory/identity.rb', line 32 def normalize_enum(value:, field:, allowed:) raise Errors::ValidationError, "#{field} must be a String or Symbol" unless text_input?(value) trimmed = value.to_s.strip raise Errors::ValidationError, "#{field} must not be empty" if trimmed.empty? candidate = trimmed.to_sym raise Errors::ValidationError, "#{field} is not one of the allowed values" unless allowed.include?(candidate) candidate end |
.normalize_text(value:, field:) ⇒ Object
19 20 21 22 23 24 25 26 27 28 29 30 |
# File 'lib/legion/extensions/llm/inventory/identity.rb', line 19 def normalize_text(value:, field:) raise Errors::ValidationError, "#{field} must be a String or Symbol" unless text_input?(value) string = value.to_s raise Errors::ValidationError, "#{field} is not valid UTF-8" unless valid_utf8?(string) trimmed = utf8(string).strip raise Errors::ValidationError, "#{field} must not be empty" if trimmed.empty? raise Errors::ValidationError, "#{field} must be NFC-normalized" unless trimmed.unicode_normalized?(:nfc) trimmed.freeze end |
.parse_lane_id(id) ⇒ Object
Bounded parse: split(':', 5) — the 5th part keeps its colons, which is load-bearing: model names contain ':' (Ollama model:tag, Bedrock model ids). Structural only — field semantics are validate_lane_id!'s.
55 56 57 58 59 60 61 62 |
# File 'lib/legion/extensions/llm/inventory/identity.rb', line 55 def parse_lane_id(id) raise Errors::ValidationError, 'lane id must be a String or Symbol' unless text_input?(id) parts = id.to_s.split(':', 5) raise Errors::ValidationError, "lane id must have exactly 5 parts, got #{parts.length}" unless parts.length == 5 parts.freeze end |
.validate_lane_id!(value:) ⇒ Object
Shape validation (R1 boundary contract): exactly 5 parts (bounded split — the model keeps its colons), part 1 in TIERS, part 4 in TYPES, parts 2/3/5 nonempty NFC. Any value that is not a 5 tuple fails the part-count check on its own — there is no special case for anything else.
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
# File 'lib/legion/extensions/llm/inventory/identity.rb', line 69 def validate_lane_id!(value:) parts = parse_lane_id(value) tier, provider_family, instance_id, type, model = parts raise Errors::ValidationError, "lane id tier must be a Taxonomies::TIERS value, got #{tier}" \ unless Taxonomies::TIERS.include?(tier.to_sym) raise Errors::ValidationError, "lane id type must be a Taxonomies::TYPES value, got #{type}" \ unless Taxonomies::TYPES.include?(type.to_sym) raise Errors::ValidationError, 'lane id provider_family must be a nonempty NFC String' \ unless nonempty_nfc?(provider_family) raise Errors::ValidationError, 'lane id instance_id must be a nonempty NFC String' \ unless nonempty_nfc?(instance_id) raise Errors::ValidationError, 'lane id model must be a nonempty NFC String' \ unless nonempty_nfc?(model) value end |