Repository navigation
feat: Add the override marker and override-affected evaluation marking - #2050
Merged
kinyoklion merged 8 commits intoOct 9, 2026
Merged
Conversation
kinyoklion
force-pushed
the
rlamb/overrides-node-filedata
branch
from
September 28, 2026 20:28
c7a8bf8 to
c32d023
Compare
kinyoklion
force-pushed
the
rlamb/overrides-node-evaluator-marking
branch
from
September 28, 2026 20:28
9e22472 to
e6ad1d1
Compare
kinyoklion
force-pushed
the
rlamb/overrides-node-filedata
branch
from
September 28, 2026 21:20
c32d023 to
8c05f0b
Compare
kinyoklion
force-pushed
the
rlamb/overrides-node-evaluator-marking
branch
from
September 28, 2026 21:20
e6ad1d1 to
30eb906
Compare
kinyoklion
force-pushed
the
rlamb/overrides-node-filedata
branch
from
September 29, 2026 15:20
8c05f0b to
79d2f0b
Compare
kinyoklion
force-pushed
the
rlamb/overrides-node-evaluator-marking
branch
from
September 29, 2026 15:20
30eb906 to
11aaea9
Compare
kinyoklion
added this pull request to stack #2061
September 30, 2026 17:08
Contributor
|
@launchdarkly/js-sdk-common size report |
Contributor
|
@launchdarkly/js-client-sdk size report |
Contributor
|
@launchdarkly/js-client-sdk-common size report |
kinyoklion
force-pushed
the
rlamb/overrides-node-filedata
branch
from
September 30, 2026 18:17
79d2f0b to
3b34072
Compare
kinyoklion
force-pushed
the
rlamb/overrides-node-evaluator-marking
branch
from
September 30, 2026 18:17
11aaea9 to
91d45a2
Compare
kinyoklion
removed this pull request from stack #2061
September 30, 2026 18:37
kinyoklion
force-pushed
the
rlamb/overrides-node-filedata
branch
from
September 30, 2026 20:16
3b34072 to
484b8cf
Compare
kinyoklion
force-pushed
the
rlamb/overrides-node-evaluator-marking
branch
from
September 30, 2026 20:16
91d45a2 to
7874143
Compare
kinyoklion
changed the base branch from
rlamb/overrides-node-filedata
to
rlamb/overrides-node-file-poller
September 30, 2026 20:16
kinyoklion
force-pushed
the
rlamb/overrides-node-file-poller
branch
from
September 30, 2026 20:23
487be22 to
4376e71
Compare
kinyoklion
force-pushed
the
rlamb/overrides-node-evaluator-marking
branch
from
September 30, 2026 20:23
7874143 to
4ecf628
Compare
kinyoklion
force-pushed
the
rlamb/overrides-node-file-poller
branch
from
September 30, 2026 21:01
4376e71 to
6478cbc
Compare
kinyoklion
force-pushed
the
rlamb/overrides-node-evaluator-marking
branch
from
September 30, 2026 21:01
4ecf628 to
2be4e36
Compare
kinyoklion
force-pushed
the
rlamb/overrides-node-file-poller
branch
from
September 30, 2026 21:04
6478cbc to
cf939a8
Compare
kinyoklion
force-pushed
the
rlamb/overrides-node-evaluator-marking
branch
from
September 30, 2026 21:04
2be4e36 to
fa5493d
Compare
kinyoklion
force-pushed
the
rlamb/overrides-node-file-poller
branch
from
September 30, 2026 22:22
cf939a8 to
f2eb769
Compare
kinyoklion
force-pushed
the
rlamb/overrides-node-evaluator-marking
branch
from
September 30, 2026 22:22
fa5493d to
f8012e2
Compare
kinyoklion
force-pushed
the
rlamb/overrides-node-file-poller
branch
from
September 30, 2026 22:27
f2eb769 to
1ca25de
Compare
kinyoklion
force-pushed
the
rlamb/overrides-node-evaluator-marking
branch
from
September 30, 2026 22:27
f8012e2 to
5605b28
Compare
kinyoklion
force-pushed
the
rlamb/overrides-node-file-poller
branch
from
October 1, 2026 23:07
1ca25de to
6150019
Compare
kinyoklion
force-pushed
the
rlamb/overrides-node-evaluator-marking
branch
from
October 1, 2026 23:07
5605b28 to
f5a88e9
Compare
kinyoklion
force-pushed
the
rlamb/overrides-node-file-poller
branch
from
October 1, 2026 23:52
6150019 to
8f495fe
Compare
kinyoklion
force-pushed
the
rlamb/overrides-node-evaluator-marking
branch
from
October 1, 2026 23:52
f5a88e9 to
08abea8
Compare
kinyoklion
force-pushed
the
rlamb/overrides-node-file-poller
branch
from
October 3, 2026 00:40
8f495fe to
4c0b961
Compare
kinyoklion
force-pushed
the
rlamb/overrides-node-evaluator-marking
branch
from
October 3, 2026 00:40
08abea8 to
4b7069e
Compare
joker23
approved these changes
Oct 5, 2026
kinyoklion
force-pushed
the
rlamb/overrides-node-file-poller
branch
from
October 5, 2026 22:32
4c0b961 to
098d985
Compare
kinyoklion
force-pushed
the
rlamb/overrides-node-evaluator-marking
branch
from
October 5, 2026 22:32
554cfbd to
14bcbd6
Compare
kinyoklion
force-pushed
the
rlamb/overrides-node-file-poller
branch
from
October 5, 2026 22:45
098d985 to
d7729d8
Compare
kinyoklion
force-pushed
the
rlamb/overrides-node-evaluator-marking
branch
from
October 5, 2026 22:45
14bcbd6 to
cb45af0
Compare
kinyoklion
force-pushed
the
rlamb/overrides-node-file-poller
branch
from
October 8, 2026 16:38
d7729d8 to
b2343d0
Compare
kinyoklion
force-pushed
the
rlamb/overrides-node-evaluator-marking
branch
from
October 8, 2026 16:38
cb45af0 to
9b941d7
Compare
kinyoklion
force-pushed
the
rlamb/overrides-node-file-poller
branch
from
October 8, 2026 22:17
b2343d0 to
af68e40
Compare
kinyoklion
force-pushed
the
rlamb/overrides-node-evaluator-marking
branch
from
October 8, 2026 22:17
9b941d7 to
50819bc
Compare
kinyoklion
force-pushed
the
rlamb/overrides-node-file-poller
branch
from
October 8, 2026 22:19
af68e40 to
fecb728
Compare
kinyoklion
force-pushed
the
rlamb/overrides-node-evaluator-marking
branch
from
October 8, 2026 22:19
50819bc to
4550837
Compare
kinyoklion
force-pushed
the
rlamb/overrides-node-file-poller
branch
from
October 8, 2026 22:35
fecb728 to
f703d00
Compare
kinyoklion
force-pushed
the
rlamb/overrides-node-evaluator-marking
branch
from
October 8, 2026 22:35
4550837 to
8650066
Compare
kinyoklion
force-pushed
the
rlamb/overrides-node-file-poller
branch
from
October 9, 2026 18:49
f703d00 to
6d3ca83
Compare
kinyoklion
force-pushed
the
rlamb/overrides-node-evaluator-marking
branch
from
October 9, 2026 18:49
8650066 to
405de3e
Compare
Base automatically changed from
rlamb/overrides-node-file-poller
to
feat/overrides
October 9, 2026 19:56
Adds the model and evaluator changes that the flag overrides feature of the OVERRIDE specification builds on. Flag and segment definitions can carry an override marker. The marker lives under a reserved, namespaced key that only the overrideMarker module names, so it cannot collide with a data model field. The serializer omits it, so it never leaves the process. Only the SDK's override store sets it. The evaluator marks an evaluation as override-affected when any definition it read carries the marker: the evaluated flag, a prerequisite flag at any depth, or a segment consulted during matching, whether or not the segment matched. The marking propagates upward only. A prerequisite evaluation starts its own marker and merges it into its parent's marker when it completes, so the record of a prerequisite reflects only the definitions that its own evaluation read. Error results are marked too. The evaluation reason gains an optional overrideAffected indicator that is set only when true, and the evaluation result carries the same marking as a scalar so that event generation does not need to read the reason. Migration operation events keep the indicator on their evaluation reason.
…gment only A property of the same name inside a variation value or a clause value is data and is stored unchanged.
… module Flag and Segment extend OverrideMarkable instead of each declaring the key. The interface is no longer tagged internal because the bundled typings of Flag and Segment reference it.
kinyoklion
force-pushed
the
rlamb/overrides-node-evaluator-marking
branch
from
October 9, 2026 19:58
405de3e to
95c87a5
Compare
…definition The marker was read through the prototype chain while the strip removes own keys only, so a definition that inherited the key could read as an override after a copy with assignment semantics. The marker now counts only as an own property that is exactly true. The strip threw on a null segment entry, which processSegment tolerated before the marker was added, so a payload with such an entry was rejected. The strip now leaves a value that is not an object alone. Tests folded in from the review: edge cases of the marking (prerequisites that are off, fail, or are never read; segments behind failing clauses, in cycles, and in big segment stores; shared reason objects; interleaved evaluations) and the marker outside the evaluator (all-flags state, ingest paths, serializers, persistent store round trip). Negative controls: the null-tolerance test fails when the guard is removed; the own-property test fails when the hasOwnProperty check is removed.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR is based on the shared file data branch because it builds on the same feature branch history and should merge after it.
This change adds the model and evaluator work that the flag overrides feature of the OVERRIDE specification builds on. Nothing in the SDK sets the marker yet, so the SDK's behavior is unchanged until the override store lands.
Flag and segment definitions can carry an override marker. The Node SDK stores definitions in their JSON data model form, so the marker lives under a reserved, namespaced key. Only the new
overrideMarkermodule names that key. Other code reads or strips the marker through its functions. The serializer omits the marker at the root of a flag or segment, so it never leaves the process, and leaves nested values untouched. Definitions read from LaunchDarkly or from a store lose the key as they are ingested, so only the override store can set it. Only the SDK's override store will set it, on the entries it holds.The evaluator marks an evaluation as override-affected when any definition it read carries the marker: the evaluated flag, a prerequisite flag at any depth, or a segment consulted during matching, whether or not the segment matched. The marking propagates upward only. A prerequisite evaluation starts its own marker from its own definition and merges it into its parent's marker when it completes, so the record of a prerequisite reflects only the definitions that its own evaluation read. Error results the evaluator produces are marked too, so a malformed override definition yields the caller's default with a marked error reason. The client's own replacement of a result on a requested-type mismatch keeps the marking in the override layer change that follows, where the marker is first set.
The evaluation reason gains an optional
overrideAffectedindicator that is set only when true, following theinExperimentprecedent. The evaluation result carries the same marking as a scalar so that event generation can key on it without reading the reason. Migration operation events keep the indicator on their evaluation reason when it is true. The OpenFeature provider reports it in flag metadata, following theinExperimentprecedent.The tests mirror the Go evaluation library's marking tests: direct marking for off, fallthrough, rule match, and error results, prerequisite records at depth one and two, an unaffected sibling prerequisite, segments matched, not matched, negated, referenced through another segment, and resolved through big segment membership, unresolvable definitions, and the agreement between the result scalar and the reason indicator.
SDK-3247
Note
Overview
Introduces experimental flag override plumbing: flag/segment definitions can carry an internal
_sdk_overridemarker (set only by the future override store), and evaluations exposeoverrideAffectedon the reason and result when any read definition was override-sourced—directly or via prerequisites/segments at any depth.The evaluator tracks marking per evaluation (including prerequisite records and segment reads, even on non-match/negated clauses), merges it up the prerequisite tree without mutating shared reason singletons, and omits
overrideAffectedfrom JSON unless it istrue(same pattern asinExperiment). Ingest/serialization strips root_sdk_overridefrom LD payloads and persistent-store round-trips while preserving nested customer data that happens to use the same key name.OpenFeature flag metadata and migration op event conversion forward
overrideAffectedwhen true. Until the override store lands, nothing sets the marker, so runtime behavior for normal LD data should stay the same aside from the new optional fields and strip-on-ingest safety.Reviewed by Cursor Bugbot for commit c97929f. Bugbot is set up for automated code reviews on this repo. Configure here.