Class: CommandTower::Configuration::Registry::ClientCompatibility::Config
- Inherits:
-
Object
- Object
- CommandTower::Configuration::Registry::ClientCompatibility::Config
- Defined in:
- lib/command_tower/configuration/registry/client_compatibility/config.rb
Overview
Two-source registry composing platform-global policy, named client
contracts, capability-scoped entity requirements, and host bindings.
Mirrors the principal_capabilities / admin_workspace / audit
registry pattern (CT-owned vs host-owned, finalize!/freeze,
reset_host_definitions! for specs). Authority §5-§9.
V1 ships with an empty CommandTower-owned catalog by design: no platform requires any contract or entity requirement out of the box.
Constant Summary collapse
- PLATFORMS =
%i[web ios android].freeze
- MODES =
%i[observe enforce].freeze
- CONTRACT_ID =
/\A[a-z][a-z0-9_]*(\.[a-z0-9][a-z0-9_]*)*\z/- PLATFORM_CONTRACTS =
CommandTower-owned seed catalog. Deliberately empty for V1 — see authority §7.5. Do not seed placeholder/fictional contracts here.
[].freeze
- PLATFORM_ENTITY_REQUIREMENTS =
{}.freeze
Instance Attribute Summary collapse
-
#mode ⇒ Object
Returns the value of attribute mode.
Instance Method Summary collapse
-
#apply_env_overlay!(env: ENV) ⇒ Object
Process-level ENV overlays (never the client's own headers).
- #bind(contract_id) {|definition| ... } ⇒ Object
- #binding_for(contract_id) ⇒ Object
- #client_contract(name, owner: :host) ⇒ Object
- #configured_platforms ⇒ Object
- #contract_registered?(name) ⇒ Boolean
- #entity(name, owner: :host) {|definition| ... } ⇒ Object
- #entity_requirement(name) ⇒ Object
- #finalize! ⇒ Object
- #finalized? ⇒ Boolean
-
#initialize ⇒ Config
constructor
A new instance of Config.
-
#opted_in? ⇒ Boolean
Whether the host has meaningfully engaged this registry at all.
- #platform(name) {|definition| ... } ⇒ Object
- #platform_policy(name) ⇒ Object
- #registered_entity_requirement?(name) ⇒ Boolean
- #reset_host_definitions! ⇒ Object
-
#validate!(entities) ⇒ Object
Boot-time fail-closed validation (authority §9).
Constructor Details
#initialize ⇒ Config
Returns a new instance of Config.
34 35 36 37 38 39 40 41 42 |
# File 'lib/command_tower/configuration/registry/client_compatibility/config.rb', line 34 def initialize @mode = :observe @platforms = {} @contracts = {} @entity_requirements = {} @bindings = {} @finalized = false seed_platform_catalog! end |
Instance Attribute Details
#mode ⇒ Object
Returns the value of attribute mode.
32 33 34 |
# File 'lib/command_tower/configuration/registry/client_compatibility/config.rb', line 32 def mode @mode end |
Instance Method Details
#apply_env_overlay!(env: ENV) ⇒ Object
Process-level ENV overlays (never the client's own headers).
COMMAND_TOWER_CLIENT_COMPATIBILITY_MODE may set observe/enforce.
COMMAND_TOWER_CLIENT_COMPATIBILITY_MINIMUM_{WEB,IOS,ANDROID} may
only RAISE an already-configured platform's minimum — never lower
it, and never configure a platform the host did not enable.
206 207 208 209 210 211 212 213 214 215 |
# File 'lib/command_tower/configuration/registry/client_compatibility/config.rb', line 206 def (env: ENV) raise_if_finalized! = env["COMMAND_TOWER_CLIENT_COMPATIBILITY_MODE"] self.mode = if .present? PLATFORMS.each { |platform| (platform, env:) } self end |
#bind(contract_id) {|definition| ... } ⇒ Object
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 |
# File 'lib/command_tower/configuration/registry/client_compatibility/config.rb', line 100 def bind(contract_id) raise_if_finalized! normalized = normalize_contract_id!(contract_id) unless @contracts.key?(normalized) raise CommandTower::ClientCompatibility::UnknownClientContractError, "cannot bind unknown client contract #{normalized}" end if @bindings.key?(normalized) raise CommandTower::ClientCompatibility::DuplicateBindingError, "client contract #{normalized} is already bound" end definition = BindingDefinition.new yield definition if block_given? definition.validate!(contract_id: normalized) @bindings[normalized] = definition definition end |
#binding_for(contract_id) ⇒ Object
120 121 122 123 124 |
# File 'lib/command_tower/configuration/registry/client_compatibility/config.rb', line 120 def binding_for(contract_id) @bindings[normalize_contract_id!(contract_id)] rescue CommandTower::ClientCompatibility::InvalidContractIdError nil end |
#client_contract(name, owner: :host) ⇒ Object
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 |
# File 'lib/command_tower/configuration/registry/client_compatibility/config.rb', line 73 def client_contract(name, owner: :host) raise_if_finalized! normalized = normalize_contract_id!(name) existing = @contracts[normalized] if existing if existing.owner == :command_tower && owner.to_sym == :host raise CommandTower::ClientCompatibility::HostOverrideError, "host cannot redefine CommandTower-owned client contract #{normalized}" end raise CommandTower::ClientCompatibility::DuplicateContractError, "client contract #{normalized} is already registered" end definition = ContractDefinition.new definition.id = normalized definition.owner = owner.to_sym @contracts[normalized] = definition definition end |
#configured_platforms ⇒ Object
65 66 67 |
# File 'lib/command_tower/configuration/registry/client_compatibility/config.rb', line 65 def configured_platforms @platforms.keys.dup.freeze end |
#contract_registered?(name) ⇒ Boolean
94 95 96 97 98 |
# File 'lib/command_tower/configuration/registry/client_compatibility/config.rb', line 94 def contract_registered?(name) @contracts.key?(normalize_contract_id!(name)) rescue CommandTower::ClientCompatibility::InvalidContractIdError false end |
#entity(name, owner: :host) {|definition| ... } ⇒ Object
126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 |
# File 'lib/command_tower/configuration/registry/client_compatibility/config.rb', line 126 def entity(name, owner: :host) raise_if_finalized! normalized = normalize_entity_name!(name) existing = @entity_requirements[normalized] if existing if existing.owner == :command_tower && owner.to_sym == :host raise CommandTower::ClientCompatibility::HostOverrideError, "host cannot redefine CommandTower-owned client compatibility entity requirement #{normalized}" end raise CommandTower::ClientCompatibility::DuplicateEntityRequirementError, "client compatibility entity requirement #{normalized} is already registered" end definition = EntityRequirementDefinition.new yield definition if block_given? definition.owner = owner definition.validate_definition!(name: normalized) @entity_requirements[normalized] = definition definition end |
#entity_requirement(name) ⇒ Object
148 149 150 |
# File 'lib/command_tower/configuration/registry/client_compatibility/config.rb', line 148 def entity_requirement(name) @entity_requirements[name.to_s] end |
#finalize! ⇒ Object
168 169 170 171 172 173 174 175 176 177 178 179 180 |
# File 'lib/command_tower/configuration/registry/client_compatibility/config.rb', line 168 def finalize! (@platforms.values + @entity_requirements.values + @bindings.values).each do |definition| next unless definition.respond_to?(:class_composer_freeze_objects!) definition.class_composer_freeze_objects!(behavior: :raise, children: true) end @platforms.freeze @contracts.freeze @entity_requirements.freeze @bindings.freeze @finalized = true self end |
#finalized? ⇒ Boolean
182 183 184 |
# File 'lib/command_tower/configuration/registry/client_compatibility/config.rb', line 182 def finalized? @finalized end |
#opted_in? ⇒ Boolean
Whether the host has meaningfully engaged this registry at all. A completely untouched registry (no platforms, no host contracts, no host entity requirements, no bindings, default observe mode) is inert: evaluation is a no-op and boot MUST NOT fail on it.
160 161 162 163 164 165 166 |
# File 'lib/command_tower/configuration/registry/client_compatibility/config.rb', line 160 def opted_in? @mode == :enforce || @platforms.any? || @contracts.any? { |_id, definition| definition.owner == :host } || @entity_requirements.any? { |_name, definition| definition.owner == :host } || @bindings.any? end |
#platform(name) {|definition| ... } ⇒ Object
55 56 57 58 59 60 61 62 63 |
# File 'lib/command_tower/configuration/registry/client_compatibility/config.rb', line 55 def platform(name) raise_if_finalized! key = normalize_platform!(name) definition = @platforms[key] || PlatformDefinition.new yield definition if block_given? definition.validate_definition!(platform: key) @platforms[key] = definition definition end |
#platform_policy(name) ⇒ Object
69 70 71 |
# File 'lib/command_tower/configuration/registry/client_compatibility/config.rb', line 69 def platform_policy(name) @platforms[name.to_s.strip.downcase.to_sym] end |
#registered_entity_requirement?(name) ⇒ Boolean
152 153 154 |
# File 'lib/command_tower/configuration/registry/client_compatibility/config.rb', line 152 def registered_entity_requirement?(name) @entity_requirements.key?(name.to_s) end |
#reset_host_definitions! ⇒ Object
217 218 219 220 221 222 223 224 225 |
# File 'lib/command_tower/configuration/registry/client_compatibility/config.rb', line 217 def reset_host_definitions! thaw_for_test! @platforms = {} @contracts.delete_if { |_id, definition| definition.owner == :host } @entity_requirements.delete_if { |_name, definition| definition.owner == :host } @bindings = {} @mode = :observe self end |
#validate!(entities) ⇒ Object
Boot-time fail-closed validation (authority §9). No-op unless the
host has opted in (see opted_in?).
188 189 190 191 192 193 194 195 196 197 198 199 |
# File 'lib/command_tower/configuration/registry/client_compatibility/config.rb', line 188 def validate!(entities) return self unless opted_in? if @platforms.empty? raise CommandTower::ClientCompatibility::NoConfiguredPlatformsError, "client_compatibility is configured but declares zero platforms" end validate_entity_requirements!(entities) validate_bindings! self end |