quonfig 0.0.19 → 0.0.20

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: f71f10c80365079815e7b7d7f2a9a8926ecfc358697505bb3c6bd3f2e6142976
4
- data.tar.gz: 3d0988da2eb9a17457dc53c358e32a55aaa17f59e1c7c280db5db52b3eb991fc
3
+ metadata.gz: a08513df922f41ef1dc16b37bb31b226e71aadaa38f324bdc223a90c4371b1a6
4
+ data.tar.gz: ae7f4292d6dba19047434eb39047f004269a50a59e39926ea02363a51b0a99f5
5
5
  SHA512:
6
- metadata.gz: e019ac9393b2644208aaa79fbbed9bfe0a27e346413ffac2cd126d47fd9ffa114a1af4bfcd597b527577935a586ea6636aa6e8c96be8ee657889bc324d9ea38c
7
- data.tar.gz: 89026759a78f4219766b14366630a5df3a3126884c5bfa721764cffdf6799c8f47df5be1245c86c8966aedbbb9a4508b65d53a400cd3c6e4308f872bc975f6ce
6
+ metadata.gz: bf23519f237e32d9c56453dcb4614a9540ce51094bb7e873c1787abf6ecf672fd0f78e9228fbc477d7f4732cff6d026f437ff4c91d08a47ebca6773b96d004ab
7
+ data.tar.gz: cd804bde09b2f3795a6bc42f2d73483153ec8a85b7e833bdd973080edd8b02d31ba5977d1fc954441e41ac7e860b28925ae24a5a40c509c355bcd999be56b71e
data/CHANGELOG.md CHANGED
@@ -1,5 +1,10 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.0.20 - 2026-05-29
4
+
5
+ - **Fix (delivery): derive evaluator env from `meta.environment` in HTTP+SSE delivery mode (qfg-xpln.2).** Per-environment overrides were not being applied when the SDK ran in delivery mode (HTTP fetch + SSE stream). The evaluator now derives its `env_id` from the authoritative `meta.environment` carried on every delivery envelope, so environment-scoped rules and overrides resolve correctly against the environment api-delivery actually served — matching datadir-mode behavior.
6
+ - **Fix (options): an explicit environment pin is datadir-only; ignored in delivery mode with a WARN (qfg-pinh).** In delivery mode the served envelope's `meta.environment` is authoritative — the environment is decided server-side by api-delivery, not by the client. A client-supplied environment pin (`with_environment` / `QUONFIG_ENVIRONMENT`) is therefore only meaningful in datadir mode. In delivery mode the pin is now ignored and a one-time WARN is logged so the conflict is visible rather than silently misleading.
7
+
3
8
  ## 0.0.19 - 2026-05-28
4
9
 
5
10
  - **Deprecation (context): `in_context` is now a deprecated alias of `with_context` (qfg-e0kk).** The two methods have always been runtime-identical — both accept a properties hash and either yield a `Quonfig::BoundClient` to a given block or return the BoundClient directly. As part of the sdk-1.0 unification, every SDK in the family is converging on the `with_context` family; sdk-ruby keeps `in_context` as a YARD-`@deprecated` alias for the 1.0.0 cycle so existing customer code (especially Prefab-fork lineage call sites) keeps working without a runtime warning. Implementation collapses to a one-line forward (`in_context` now calls `with_context`), and the README example is updated to use `with_context`. Slated for removal in 2.0.0.
@@ -714,6 +714,14 @@ module Quonfig
714
714
  old_keys = @store.keys.to_set
715
715
  (old_keys - new_keys).each { |k| @store.delete(k) }
716
716
  envelope.configs.each { |cfg| @store.set(cfg['key'], cfg) }
717
+ # qfg-pinh: evaluate against the installed envelope's meta.environment,
718
+ # matching sdk-go. In datadir mode the loader stamps meta.environment =
719
+ # the resolved env (the `environment:` pin or QUONFIG_ENVIRONMENT), so
720
+ # this also covers the env-var-only case where @options.environment is
721
+ # nil at evaluator construction.
722
+ meta = envelope.respond_to?(:meta) ? envelope.meta : nil
723
+ env_id = meta && (meta['environment'] || meta[:environment])
724
+ @evaluator.env_id = env_id if env_id && !env_id.to_s.empty?
717
725
  record_refresh!
718
726
  end
719
727
 
@@ -761,6 +769,8 @@ module Quonfig
761
769
  def initialize_network_mode
762
770
  raise Quonfig::Errors::InvalidSdkKeyError, @options.sdk_key if @options.sdk_key.nil? || @options.sdk_key.to_s.strip.empty?
763
771
 
772
+ warn_if_pin_ignored_in_delivery_mode
773
+
764
774
  @config_loader = Quonfig::ConfigLoader.new(@store, @options)
765
775
 
766
776
  perform_initial_fetch
@@ -791,10 +801,52 @@ module Quonfig
791
801
  if result == :failed
792
802
  handle_init_failure(RuntimeError.new('Config fetch failed against all api_urls'))
793
803
  else
804
+ sync_evaluator_env_id!
794
805
  record_refresh!
795
806
  end
796
807
  end
797
808
 
809
+ # qfg-pinh: In SDK-key DELIVERY mode the server's `meta.environment` is
810
+ # AUTHORITATIVE. The server scopes each config to a single environment and
811
+ # reports the active env id in `meta.environment` (the loader captures it
812
+ # as @config_loader.environment_id). The evaluator must always evaluate
813
+ # against that installed env id — matching sdk-go, where eval never
814
+ # branches on the pin (c.envID = envelope.Meta.Environment, quonfig.go:850).
815
+ #
816
+ # An explicit environment pin (`environment:` option / QUONFIG_ENVIRONMENT)
817
+ # is DATADIR-ONLY: in delivery mode it is IGNORED (it only feeds the datadir
818
+ # loader, which stamps meta.environment = pin). So we always adopt the
819
+ # server's env id here regardless of the pin. A WARN is emitted once at init
820
+ # (see #warn_if_pin_ignored_in_delivery_mode) when a pin is set in delivery
821
+ # mode so customers aren't surprised that it has no effect.
822
+ #
823
+ # qfg-xpln.2 originally only adopted the server env when NO pin was set,
824
+ # which let the pin win in delivery mode — qfg-pinh reverses that.
825
+ def sync_evaluator_env_id!
826
+ return unless @config_loader.respond_to?(:environment_id)
827
+
828
+ server_env = @config_loader.environment_id
829
+ @evaluator.env_id = server_env if server_env && !server_env.to_s.empty?
830
+ end
831
+
832
+ # qfg-pinh: an explicit environment pin (`environment:` option or
833
+ # QUONFIG_ENVIRONMENT) is DATADIR-ONLY. In delivery (SDK-key) mode the
834
+ # active environment is determined by the SDK key and reported via
835
+ # `meta.environment`, so the pin is ignored. Warn once at init so the
836
+ # customer isn't surprised the setting has no effect. Fired only on the
837
+ # delivery-mode init path (datadir mode honors the pin and never calls
838
+ # this).
839
+ def warn_if_pin_ignored_in_delivery_mode
840
+ env = @options.environment
841
+ return if env.nil? || env.to_s.empty?
842
+
843
+ LOG.warn(
844
+ "[quonfig] environment '#{env}' was set but the client is in delivery " \
845
+ '(SDK-key) mode; the active environment is determined by the SDK key, ' \
846
+ 'so this setting is ignored (it applies only when loading from a local data dir)'
847
+ )
848
+ end
849
+
798
850
  def handle_init_failure(err)
799
851
  if @options.on_init_failure == Quonfig::Options::ON_INITIALIZATION_FAILURE::RETURN
800
852
  LOG.warn "[quonfig] Initialization did not complete cleanly; continuing with empty store: #{err.message}"
@@ -821,6 +873,7 @@ module Quonfig
821
873
 
822
874
  begin
823
875
  @config_loader.apply_envelope(envelope)
876
+ sync_evaluator_env_id!
824
877
  handle_sse_state_change(:connected)
825
878
  record_refresh!
826
879
  rescue StandardError => e
@@ -858,6 +911,7 @@ module Quonfig
858
911
  break if stopped_ref.call
859
912
 
860
913
  @config_loader.fetch!
914
+ sync_evaluator_env_id!
861
915
  record_refresh!
862
916
  notify_delivered.call
863
917
  notify_on_update_callback
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Quonfig
4
- VERSION = '0.0.19'
4
+ VERSION = '0.0.20'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: quonfig
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.19
4
+ version: 0.0.20
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeff Dwyer
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-05-28 00:00:00.000000000 Z
11
+ date: 2026-05-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport