From a735ff81a1db0329b349cdb41bcda723dddbde82 Mon Sep 17 00:00:00 2001 From: Todd Baert Date: Mon, 26 Aug 2024 14:43:17 -0400 Subject: [PATCH 01/10] feat: tracking Signed-off-by: Todd Baert --- specification.json | 51 +++++++++++ specification/glossary.md | 5 ++ specification/sections/02-providers.md | 31 +++++++ specification/sections/06-tracking.md | 117 ++++++++++++++++++------- specification/types.md | 8 ++ 5 files changed, 180 insertions(+), 32 deletions(-) diff --git a/specification.json b/specification.json index 652c2c98..e6ccfa97 100644 --- a/specification.json +++ b/specification.json @@ -508,6 +508,13 @@ "RFC 2119 keyword": "MAY", "children": [] }, + { + "id": "Condition 2.7.1", + "machine_id": "condition_2_7_1", + "content": "The `provider` MAY define a function for tracking the occurrence of a particular user action or application state, with parameters `occurrence key` (string, required), `evaluation context` (optional) and `occurrence details` (optional) which returns nothing.", + "RFC 2119 keyword": "MAY", + "children": [] + }, { "id": "Requirement 3.1.1", "machine_id": "requirement_3_1_1", @@ -1044,6 +1051,50 @@ "content": "If the provider emits an event, the value of the client's `provider status` MUST be updated accordingly.", "RFC 2119 keyword": "MUST", "children": [] + }, + { + "id": "Condition 6.1.1", + "machine_id": "condition_6_1_1", + "content": "The implementation uses the dynamic-context paradigm.", + "RFC 2119 keyword": null, + "children": [ + { + "id": "Conditional Requirement 6.1.1.1", + "machine_id": "conditional_requirement_6_1_1_1", + "content": "The `client` MUST define a function for tracking the occurrence of a particular action or application state, with parameters `occurrence key` (string, required), `evaluation context` (optional) and `occurrence details` (optional) which returns nothing.", + "RFC 2119 keyword": "MUST", + "children": [] + } + ] + }, + { + "id": "Condition 6.1.2", + "machine_id": "condition_6_1_2", + "content": "The implementation uses the static-context paradigm.", + "RFC 2119 keyword": null, + "children": [ + { + "id": "Conditional Requirement 6.1.2.1", + "machine_id": "conditional_requirement_6_1_2_1", + "content": "The `client` MUST define a function for tracking the occurrence of a particular action or application state, with parameters `occurrence key` (string, required) and `occurrence details` (optional) which returns nothing.", + "RFC 2119 keyword": "MUST", + "children": [] + } + ] + }, + { + "id": "Requirement 6.1.3", + "machine_id": "requirement_6_1_3", + "content": "The evaluation context passed to the provider's track function MUST be merged in the order: API (global; lowest precedence) - transaction - client - invocation (highest precedence), with duplicate values being overwritten.", + "RFC 2119 keyword": "MUST", + "children": [] + }, + { + "id": "Requirement 6.1.4", + "machine_id": "requirement_6_1_4", + "content": "If the client's `track` function is called and the associated provider does not implement tracking, the client's `track` function MUST no-op.", + "RFC 2119 keyword": "MUST", + "children": [] } ] } \ No newline at end of file diff --git a/specification/glossary.md b/specification/glossary.md index 0afba2de..5922983f 100644 --- a/specification/glossary.md +++ b/specification/glossary.md @@ -46,6 +46,7 @@ This document defines some terms that are used across this specification. - [Targeting Key](#targeting-key) - [Fractional Evaluation](#fractional-evaluation) - [Rule](#rule) + - [Tracking Occurrence](#tracking-occurrence) - [SDK Paradigms](#sdk-paradigms) - [Dynamic-Context Paradigm](#dynamic-context-paradigm) - [Static-Context Paradigm](#static-context-paradigm) @@ -200,6 +201,10 @@ Pseudorandomly resolve flag values using a context property, such as a targeting A rule is some criteria that's used to determine which variant a particular context should be mapped to. +### Tracking Occurrence + +A particular user action or application state representing a business objective or outcome, identified by a unique string, and recorded using the [tracking API](./sections/06-tracking.md). + ## SDK Paradigms Feature flag frameworks have SDKs which operate in two distinct paradigms: those designed for use with a single user client application (e.g. mobile phones, single-page web apps), and those designed for multi-user applications, such as web server applications. Some parts of the OpenFeature specification diverge depending on the paradigm. diff --git a/specification/sections/02-providers.md b/specification/sections/02-providers.md index 581c8579..4e94426b 100644 --- a/specification/sections/02-providers.md +++ b/specification/sections/02-providers.md @@ -261,3 +261,34 @@ class MyProvider implements Provider { Providers may maintain remote connections, timers, threads or other constructs that need to be appropriately disposed of. Provider authors may implement a `shutdown` function to perform relevant clean-up actions. Alternatively, implementations might leverage language idioms such as auto-disposable interfaces or some means of cancellation signal propagation to allow for graceful shutdown. + +### 2.7. Tracking Support + +[![experimental](https://img.shields.io/static/v1?label=Status&message=experimental&color=orange)](https://github.com/open-feature/spec/tree/main/specification#experimental) + +Some flag management systems support tracking functionality, which associates feature flag evaluations with subsequent user actions or application state. + +See [tracking](./06-tracking.md). + +#### Condition 2.7.1 + +> The `provider` **MAY** define a function for tracking the occurrence of a particular user action or application state, with parameters `occurrence key` (string, required), `evaluation context` (optional) and `occurrence details` (optional) which returns nothing. + +```java +class MyProvider implements Tracking { + //... + + /** + * Record a tracking occurrence. + */ + void track(String occurrenceKey, OccurrenceDetails details, EvaluationContext context): void; + + //... +} +``` + +The track function is a void function (function returning nothing). +The track function performs side effects required to record the `occurrence` in question, which may include network activity or other I/O; this I/O should not block the function call. +Providers should be careful to complete any communication or flush any relevant uncommitted tracking data before they shut down. + +See [shutdown](#25-shutdown). \ No newline at end of file diff --git a/specification/sections/06-tracking.md b/specification/sections/06-tracking.md index 0e29203e..85417f18 100644 --- a/specification/sections/06-tracking.md +++ b/specification/sections/06-tracking.md @@ -10,35 +10,88 @@ toc_max_heading_level: 4 ## Overview -Experimentation is a primary use case for feature flags. -In practice, this often means flag variants are assigned to users at random or in accordance with a business rule, while the impact of the assigned variant on some business objective is measured. -Vendors and custom solutions often support a _tracking_ or _goal measuring_ API to facilitate the measurement of these business objectives. - -### Goals - -- Develop official terminology to support consistent implementation -- Specify a flexible API widely compatible with basic vendor functionality - - Define tracking event payload - - Define tracking event identifier - - Support A/B testing and experimentation use-cases - - Support client and server paradigms - - Provide recommendations around: - - Async vs sync - - Flushing mechanisms - - Event batching - -### Non-goals - -- Creating an experimentation platform -- Covering every user-tracking use case - - We will not define any data aggregation mechanisms - - We will not focus on "metrics", but instead, "facts" - -### Design Principles - -We value the following: - -- Adherence to, and compatibility with OpenFeature semantics -- Maximum compatibility and ease-of-adoption for existing solutions -- Minimum traffic and payload size -- Ease-of-use for application authors, integrators, and provider authors (in that order) +The `tracking API` enables the association of feature flag evaluations with subsequent actions or application states, in order to facilitate experimentation, and analysis of the impact of feature flags on business objectives. + +Combined with hooks which report feature flag evaluations to the analytics platform in question, tracking can allow for robust experimentation even for flag management systems that don't support tracking directly. + +```mermaid +sequenceDiagram + Evaluation API->>+Tracking Hook: evaluate + Tracking Hook->>Analytics Platform: before + Tracking Hook->>Analytics Platform: after + Tracking Hook->>-Evaluation API: evaluate + Evaluation API->>Analytics Platform: track +``` + +### 6.1. Tracking API + +#### Condition 6.1.1 + +> The implementation uses the dynamic-context paradigm. + +see: [dynamic-context paradigm](../glossary.md#dynamic-context-paradigm) + +##### Conditional Requirement 6.1.1.1 + +> The `client` **MUST** define a function for tracking the occurrence of a particular action or application state, with parameters `occurrence key` (string, required), `evaluation context` (optional) and `occurrence details` (optional) which returns nothing. + +```java +// example tracking occurrence recording that a subject reached a page associated with a business goal +client.track("visited-promo-page", evaluationContext); + +// example tracking occurrence recording that a subject performed an action associated with a business goal, with the occurrence details having a particular numeric value +client.track("clicked-checkout", evaluationContext, new OccurrenceDetails(99.77)): void; +``` + +See [evaluation context](../types.md#evaluation-context), [occurrence details](#62-occurrence-details). + +#### Condition 6.1.2 + +[![experimental](https://img.shields.io/static/v1?label=Status&message=experimental&color=orange)](https://github.com/open-feature/spec/tree/main/specification#experimental) + +> The implementation uses the static-context paradigm. + +see: [static-context paradigm](../glossary.md#static-context-paradigm) + +##### Conditional Requirement 6.1.2.1 + +> The `client` **MUST** define a function for tracking the occurrence of a particular action or application state, with parameters `occurrence key` (string, required) and `occurrence details` (optional) which returns nothing. + +The track function is a void function (function returning nothing). +Though it may be associated with network activity or other I/O, it need not be awaited by application authors. + +```java +// example tracking occurrence recording that a subject reached a page associated with a business goal +client.track("visited-promo-page"); + +// example tracking occurrence recording that a subject performed an action associated with a business goal, with the occurrence details having a particular numeric value +client.track("clicked-checkout", new OccurrenceDetails(99.77)): void; +``` + +#### Requirement 6.1.3 + +> The evaluation context passed to the provider's track function **MUST** be merged in the order: API (global; lowest precedence) -> transaction -> client -> invocation (highest precedence), with duplicate values being overwritten. + +The SDK passes a merged evaluation context to the provider's track function similarly to the manner it does in resolvers. + +See: [context levels and merging](./03-evaluation-context.md#32-context-levels-and-merging). + +#### Requirement 6.1.4 + +> If the client's `track` function is called and the associated provider does not implement tracking, the client's `track` function **MUST** no-op. + +## 6.2. Occurrence Details + +The `occurrence details` structure defines optional data pertinent to a particular `occurrence`. + +### Requirement 6.2.1 + +> The `occurrence details` structure **MUST** define an optional numeric `value`, associating a scalar quality with an `occurrence`. + +`Value` is a well-defined field which some providers may map to equivalent numeric values in their API. + +See [provider tracking support](./02-providers.md#27-tracking-support). + +### Requirement 6.2.2 + +> The `occurrence details` **MUST** support the inclusion of custom fields, having keys of type `string`, and values of type `boolean | string | number`. \ No newline at end of file diff --git a/specification/types.md b/specification/types.md index 91fa18e6..f658b8eb 100644 --- a/specification/types.md +++ b/specification/types.md @@ -113,6 +113,10 @@ An enumerated error code represented idiomatically in the implementation languag | PROVIDER_FATAL | The provider has entered an irrecoverable error state. | | GENERAL | The error was for a reason not enumerated above. | +### Evaluation Context + +See [evaluation context](./sections/03-evaluation-context.md). + ### Evaluation Options A structure containing the following fields: @@ -184,3 +188,7 @@ An enumeration of provider events. A function or method which can be associated with a `provider event`, and runs when that event occurs. It declares an `event details` parameter. + +### Occurrence Details + +See [occurrence details](./sections/06-tracking.md#62-occurrence-details).\ From af901e10df9759ec8f14ba8b35bf74824aa3d24f Mon Sep 17 00:00:00 2001 From: Todd Baert Date: Tue, 27 Aug 2024 10:35:43 -0400 Subject: [PATCH 02/10] Update specification/types.md Co-authored-by: Michael Beemer Signed-off-by: Todd Baert --- specification/types.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/types.md b/specification/types.md index f658b8eb..8a7e8c8c 100644 --- a/specification/types.md +++ b/specification/types.md @@ -191,4 +191,4 @@ It declares an `event details` parameter. ### Occurrence Details -See [occurrence details](./sections/06-tracking.md#62-occurrence-details).\ +See [occurrence details](./sections/06-tracking.md#62-occurrence-details). From 0ae6093c200a4e1d386e3576faefa6d54360df04 Mon Sep 17 00:00:00 2001 From: Todd Baert Date: Tue, 27 Aug 2024 10:41:37 -0400 Subject: [PATCH 03/10] Update specification/sections/02-providers.md Co-authored-by: Nicklas Lundin Signed-off-by: Todd Baert --- specification/sections/02-providers.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/sections/02-providers.md b/specification/sections/02-providers.md index 4e94426b..a55aae1a 100644 --- a/specification/sections/02-providers.md +++ b/specification/sections/02-providers.md @@ -266,7 +266,7 @@ Alternatively, implementations might leverage language idioms such as auto-dispo [![experimental](https://img.shields.io/static/v1?label=Status&message=experimental&color=orange)](https://github.com/open-feature/spec/tree/main/specification#experimental) -Some flag management systems support tracking functionality, which associates feature flag evaluations with subsequent user actions or application state. +Some flag management systems support tracking functionality, which can be used to associate feature flag evaluations with subsequent user actions or application state. See [tracking](./06-tracking.md). From 5287d2ccc7391ab610cdf12006abaabda76624f2 Mon Sep 17 00:00:00 2001 From: Todd Baert Date: Wed, 4 Sep 2024 11:18:46 -0400 Subject: [PATCH 04/10] fixup: param ordering Signed-off-by: Todd Baert --- specification/sections/02-providers.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/sections/02-providers.md b/specification/sections/02-providers.md index a55aae1a..aecdc0c2 100644 --- a/specification/sections/02-providers.md +++ b/specification/sections/02-providers.md @@ -281,7 +281,7 @@ class MyProvider implements Tracking { /** * Record a tracking occurrence. */ - void track(String occurrenceKey, OccurrenceDetails details, EvaluationContext context): void; + void track(String occurrenceKey, EvaluationContext context, OccurrenceDetails details): void; //... } From fc76498b6c101710d0fddc2c96bd73bd316b2cfc Mon Sep 17 00:00:00 2001 From: Todd Baert Date: Tue, 10 Sep 2024 14:12:57 -0400 Subject: [PATCH 05/10] fixup: fix headers, add structure to occurance details Signed-off-by: Todd Baert --- specification.json | 14 ++++++++++++++ specification/sections/06-tracking.md | 12 ++++++++---- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/specification.json b/specification.json index e6ccfa97..164dddce 100644 --- a/specification.json +++ b/specification.json @@ -1095,6 +1095,20 @@ "content": "If the client's `track` function is called and the associated provider does not implement tracking, the client's `track` function MUST no-op.", "RFC 2119 keyword": "MUST", "children": [] + }, + { + "id": "Requirement 6.2.1", + "machine_id": "requirement_6_2_1", + "content": "The `occurrence details` structure MUST define an optional numeric `value`, associating a scalar quality with an `occurrence`.", + "RFC 2119 keyword": "MUST", + "children": [] + }, + { + "id": "Requirement 6.2.2", + "machine_id": "requirement_6_2_2", + "content": "The `occurrence details` MUST support the inclusion of custom fields, having keys of type `string`, and values of type `boolean | string | number | structure`.", + "RFC 2119 keyword": "MUST", + "children": [] } ] } \ No newline at end of file diff --git a/specification/sections/06-tracking.md b/specification/sections/06-tracking.md index 85417f18..472e85b1 100644 --- a/specification/sections/06-tracking.md +++ b/specification/sections/06-tracking.md @@ -80,11 +80,11 @@ See: [context levels and merging](./03-evaluation-context.md#32-context-levels-a > If the client's `track` function is called and the associated provider does not implement tracking, the client's `track` function **MUST** no-op. -## 6.2. Occurrence Details +### 6.2. Occurrence Details The `occurrence details` structure defines optional data pertinent to a particular `occurrence`. -### Requirement 6.2.1 +#### Requirement 6.2.1 > The `occurrence details` structure **MUST** define an optional numeric `value`, associating a scalar quality with an `occurrence`. @@ -92,6 +92,10 @@ The `occurrence details` structure defines optional data pertinent to a particul See [provider tracking support](./02-providers.md#27-tracking-support). -### Requirement 6.2.2 +#### Requirement 6.2.2 -> The `occurrence details` **MUST** support the inclusion of custom fields, having keys of type `string`, and values of type `boolean | string | number`. \ No newline at end of file +> The `occurrence details` **MUST** support the inclusion of custom fields, having keys of type `string`, and values of type `boolean | string | number | structure`. + +The `occurrence details` supports the addition of arbitrary fields, including nested objects, similar to the `evaluation context` and object-typed flag values. + +See [structure](../types.md#structure), [evaluation context](.//03-evaluation-context.md). \ No newline at end of file From 5470877c9ab4b5ed85f7ceb5bf8833d1648cc300 Mon Sep 17 00:00:00 2001 From: Todd Baert Date: Tue, 17 Sep 2024 16:01:50 -0400 Subject: [PATCH 06/10] fixup: additional details Signed-off-by: Todd Baert --- specification/sections/06-tracking.md | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/specification/sections/06-tracking.md b/specification/sections/06-tracking.md index 472e85b1..7fb40213 100644 --- a/specification/sections/06-tracking.md +++ b/specification/sections/06-tracking.md @@ -40,7 +40,10 @@ see: [dynamic-context paradigm](../glossary.md#dynamic-context-paradigm) client.track("visited-promo-page", evaluationContext); // example tracking occurrence recording that a subject performed an action associated with a business goal, with the occurrence details having a particular numeric value -client.track("clicked-checkout", evaluationContext, new OccurrenceDetails(99.77)): void; +client.track("clicked-checkout", evaluationContext, new OccurrenceDetails(99.77)); + +// example tracking occurrence recording that a subject performed an action associated with a business goal, with the occurrence details having a particular numeric value +client.track("clicked-checkout", evaluationContext, new OccurrenceDetails(99.77).add("currencyCode", "USD")); ``` See [evaluation context](../types.md#evaluation-context), [occurrence details](#62-occurrence-details). @@ -65,7 +68,10 @@ Though it may be associated with network activity or other I/O, it need not be a client.track("visited-promo-page"); // example tracking occurrence recording that a subject performed an action associated with a business goal, with the occurrence details having a particular numeric value -client.track("clicked-checkout", new OccurrenceDetails(99.77)): void; +client.track("clicked-checkout", new OccurrenceDetails(99.77)); + +// example tracking occurrence recording that a subject performed an action associated with a business goal, with the occurrence details having a particular numeric and some additional details +client.track("clicked-checkout", new OccurrenceDetails(99.77).add("currencyCode", "USD")); ``` #### Requirement 6.1.3 From 6eafc40919f8bea4dde5c34ec3e51ce080a61497 Mon Sep 17 00:00:00 2001 From: Todd Baert Date: Mon, 30 Sep 2024 13:12:27 -0400 Subject: [PATCH 07/10] Update specification/sections/06-tracking.md Co-authored-by: Justin Abrahms Signed-off-by: Todd Baert --- specification/sections/06-tracking.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/sections/06-tracking.md b/specification/sections/06-tracking.md index 7fb40213..240747b7 100644 --- a/specification/sections/06-tracking.md +++ b/specification/sections/06-tracking.md @@ -10,7 +10,7 @@ toc_max_heading_level: 4 ## Overview -The `tracking API` enables the association of feature flag evaluations with subsequent actions or application states, in order to facilitate experimentation, and analysis of the impact of feature flags on business objectives. +The `tracking API` enables the association of feature flag evaluations with subsequent actions or application states, in order to facilitate experimentation and analysis of the impact of feature flags on business objectives. Combined with hooks which report feature flag evaluations to the analytics platform in question, tracking can allow for robust experimentation even for flag management systems that don't support tracking directly. From 0558fc4daa91d975ee07d93f1fc859f54b170809 Mon Sep 17 00:00:00 2001 From: Todd Baert Date: Tue, 1 Oct 2024 12:23:28 -0400 Subject: [PATCH 08/10] fixup: occurrence -> tracking event Signed-off-by: Todd Baert --- specification.json | 8 +++--- specification/glossary.md | 4 +-- specification/sections/02-providers.md | 2 +- specification/sections/06-tracking.md | 36 +++++++++++++------------- specification/types.md | 6 +++-- 5 files changed, 29 insertions(+), 27 deletions(-) diff --git a/specification.json b/specification.json index 164dddce..cdd1a4f8 100644 --- a/specification.json +++ b/specification.json @@ -1061,7 +1061,7 @@ { "id": "Conditional Requirement 6.1.1.1", "machine_id": "conditional_requirement_6_1_1_1", - "content": "The `client` MUST define a function for tracking the occurrence of a particular action or application state, with parameters `occurrence key` (string, required), `evaluation context` (optional) and `occurrence details` (optional) which returns nothing.", + "content": "The `client` MUST define a function for tracking the occurrence of a particular action or application state, with parameters `tracking event name` (string, required), `evaluation context` (optional) and `tracking event details` (optional), which returns nothing.", "RFC 2119 keyword": "MUST", "children": [] } @@ -1076,7 +1076,7 @@ { "id": "Conditional Requirement 6.1.2.1", "machine_id": "conditional_requirement_6_1_2_1", - "content": "The `client` MUST define a function for tracking the occurrence of a particular action or application state, with parameters `occurrence key` (string, required) and `occurrence details` (optional) which returns nothing.", + "content": "The `client` MUST define a function for tracking the occurrence of a particular action or application state, with parameters `tracking event name` (string, required) and `tracking event details` (optional), which returns nothing.", "RFC 2119 keyword": "MUST", "children": [] } @@ -1099,14 +1099,14 @@ { "id": "Requirement 6.2.1", "machine_id": "requirement_6_2_1", - "content": "The `occurrence details` structure MUST define an optional numeric `value`, associating a scalar quality with an `occurrence`.", + "content": "The `tracking event details` structure MUST define an optional numeric `value`, associating a scalar quality with an `tracking event`.", "RFC 2119 keyword": "MUST", "children": [] }, { "id": "Requirement 6.2.2", "machine_id": "requirement_6_2_2", - "content": "The `occurrence details` MUST support the inclusion of custom fields, having keys of type `string`, and values of type `boolean | string | number | structure`.", + "content": "The `tracking event details` MUST support the inclusion of custom fields, having keys of type `string`, and values of type `boolean | string | number | structure`.", "RFC 2119 keyword": "MUST", "children": [] } diff --git a/specification/glossary.md b/specification/glossary.md index 5922983f..7ba7780c 100644 --- a/specification/glossary.md +++ b/specification/glossary.md @@ -46,7 +46,7 @@ This document defines some terms that are used across this specification. - [Targeting Key](#targeting-key) - [Fractional Evaluation](#fractional-evaluation) - [Rule](#rule) - - [Tracking Occurrence](#tracking-occurrence) + - [Tracking Event](#tracking-event) - [SDK Paradigms](#sdk-paradigms) - [Dynamic-Context Paradigm](#dynamic-context-paradigm) - [Static-Context Paradigm](#static-context-paradigm) @@ -201,7 +201,7 @@ Pseudorandomly resolve flag values using a context property, such as a targeting A rule is some criteria that's used to determine which variant a particular context should be mapped to. -### Tracking Occurrence +### Tracking Event A particular user action or application state representing a business objective or outcome, identified by a unique string, and recorded using the [tracking API](./sections/06-tracking.md). diff --git a/specification/sections/02-providers.md b/specification/sections/02-providers.md index aecdc0c2..90a90f96 100644 --- a/specification/sections/02-providers.md +++ b/specification/sections/02-providers.md @@ -281,7 +281,7 @@ class MyProvider implements Tracking { /** * Record a tracking occurrence. */ - void track(String occurrenceKey, EvaluationContext context, OccurrenceDetails details): void; + void track(String trackingEventName, EvaluationContext context, TrackingEventDetails details): void; //... } diff --git a/specification/sections/06-tracking.md b/specification/sections/06-tracking.md index 240747b7..897c6722 100644 --- a/specification/sections/06-tracking.md +++ b/specification/sections/06-tracking.md @@ -33,20 +33,20 @@ see: [dynamic-context paradigm](../glossary.md#dynamic-context-paradigm) ##### Conditional Requirement 6.1.1.1 -> The `client` **MUST** define a function for tracking the occurrence of a particular action or application state, with parameters `occurrence key` (string, required), `evaluation context` (optional) and `occurrence details` (optional) which returns nothing. +> The `client` **MUST** define a function for tracking the occurrence of a particular action or application state, with parameters `tracking event name` (string, required), `evaluation context` (optional) and `tracking event details` (optional), which returns nothing. ```java -// example tracking occurrence recording that a subject reached a page associated with a business goal +// example tracking event recording that a subject reached a page associated with a business goal client.track("visited-promo-page", evaluationContext); -// example tracking occurrence recording that a subject performed an action associated with a business goal, with the occurrence details having a particular numeric value -client.track("clicked-checkout", evaluationContext, new OccurrenceDetails(99.77)); +// example tracking event recording that a subject performed an action associated with a business goal, with the tracking event details having a particular numeric value +client.track("clicked-checkout", evaluationContext, new TrackingEventDetails(99.77)); -// example tracking occurrence recording that a subject performed an action associated with a business goal, with the occurrence details having a particular numeric value -client.track("clicked-checkout", evaluationContext, new OccurrenceDetails(99.77).add("currencyCode", "USD")); +// example tracking event recording that a subject performed an action associated with a business goal, with the tracking event details having a particular numeric value +client.track("clicked-checkout", evaluationContext, new TrackingEventDetails(99.77).add("currencyCode", "USD")); ``` -See [evaluation context](../types.md#evaluation-context), [occurrence details](#62-occurrence-details). +See [evaluation context](../types.md#evaluation-context), [tracking event details](#62-tracking-event-details). #### Condition 6.1.2 @@ -58,20 +58,20 @@ see: [static-context paradigm](../glossary.md#static-context-paradigm) ##### Conditional Requirement 6.1.2.1 -> The `client` **MUST** define a function for tracking the occurrence of a particular action or application state, with parameters `occurrence key` (string, required) and `occurrence details` (optional) which returns nothing. +> The `client` **MUST** define a function for tracking the occurrence of a particular action or application state, with parameters `tracking event name` (string, required) and `tracking event details` (optional), which returns nothing. The track function is a void function (function returning nothing). Though it may be associated with network activity or other I/O, it need not be awaited by application authors. ```java -// example tracking occurrence recording that a subject reached a page associated with a business goal +// example tracking event recording that a subject reached a page associated with a business goal client.track("visited-promo-page"); -// example tracking occurrence recording that a subject performed an action associated with a business goal, with the occurrence details having a particular numeric value -client.track("clicked-checkout", new OccurrenceDetails(99.77)); +// example tracking event recording that a subject performed an action associated with a business goal, with the tracking event details having a particular numeric value +client.track("clicked-checkout", new TrackingEventDetails(99.77)); -// example tracking occurrence recording that a subject performed an action associated with a business goal, with the occurrence details having a particular numeric and some additional details -client.track("clicked-checkout", new OccurrenceDetails(99.77).add("currencyCode", "USD")); +// example tracking event recording that a subject performed an action associated with a business goal, with the tracking event details having a particular numeric and some additional details +client.track("clicked-checkout", new TrackingEventDetails(99.77).add("currencyCode", "USD")); ``` #### Requirement 6.1.3 @@ -86,13 +86,13 @@ See: [context levels and merging](./03-evaluation-context.md#32-context-levels-a > If the client's `track` function is called and the associated provider does not implement tracking, the client's `track` function **MUST** no-op. -### 6.2. Occurrence Details +### 6.2. Tracking Event Details -The `occurrence details` structure defines optional data pertinent to a particular `occurrence`. +The `tracking event details` structure defines optional data pertinent to a particular `tracking event`. #### Requirement 6.2.1 -> The `occurrence details` structure **MUST** define an optional numeric `value`, associating a scalar quality with an `occurrence`. +> The `tracking event details` structure **MUST** define an optional numeric `value`, associating a scalar quality with an `tracking event`. `Value` is a well-defined field which some providers may map to equivalent numeric values in their API. @@ -100,8 +100,8 @@ See [provider tracking support](./02-providers.md#27-tracking-support). #### Requirement 6.2.2 -> The `occurrence details` **MUST** support the inclusion of custom fields, having keys of type `string`, and values of type `boolean | string | number | structure`. +> The `tracking event details` **MUST** support the inclusion of custom fields, having keys of type `string`, and values of type `boolean | string | number | structure`. -The `occurrence details` supports the addition of arbitrary fields, including nested objects, similar to the `evaluation context` and object-typed flag values. +The `tracking event details` supports the addition of arbitrary fields, including nested objects, similar to the `evaluation context` and object-typed flag values. See [structure](../types.md#structure), [evaluation context](.//03-evaluation-context.md). \ No newline at end of file diff --git a/specification/types.md b/specification/types.md index 8a7e8c8c..b434bfd6 100644 --- a/specification/types.md +++ b/specification/types.md @@ -189,6 +189,8 @@ An enumeration of provider events. A function or method which can be associated with a `provider event`, and runs when that event occurs. It declares an `event details` parameter. -### Occurrence Details +### Tracking Event Details -See [occurrence details](./sections/06-tracking.md#62-occurrence-details). +A structure which supports definition of arbitrary properties, including nested objects, similar to the `evaluation context` and object-typed flag values. + +See [tracking event details](./sections/06-tracking.md#62-tracking-event-details), [evaluation context](#evaluation-context). From b4ccd5357980ba4295b44aae08b94876da42cf74 Mon Sep 17 00:00:00 2001 From: Todd Baert Date: Tue, 1 Oct 2024 12:33:09 -0400 Subject: [PATCH 09/10] fixup: move tracking event type to common Signed-off-by: Todd Baert --- specification/glossary.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/specification/glossary.md b/specification/glossary.md index 7ba7780c..fc9de14e 100644 --- a/specification/glossary.md +++ b/specification/glossary.md @@ -36,6 +36,7 @@ This document defines some terms that are used across this specification. - [Transaction Context Propagator](#transaction-context-propagator) - [Evaluating Flag Values](#evaluating-flag-values) - [Resolving Flag Values](#resolving-flag-values) + - [Tracking Event](#tracking-event) - [Flagging specifics](#flagging-specifics) - [Flag](#flag) - [Flag Set](#flag-set) @@ -46,7 +47,6 @@ This document defines some terms that are used across this specification. - [Targeting Key](#targeting-key) - [Fractional Evaluation](#fractional-evaluation) - [Rule](#rule) - - [Tracking Event](#tracking-event) - [SDK Paradigms](#sdk-paradigms) - [Dynamic-Context Paradigm](#dynamic-context-paradigm) - [Static-Context Paradigm](#static-context-paradigm) @@ -149,6 +149,10 @@ The process of retrieving a feature flag value in it's entirety, including: The process of a provider retrieving a feature flag value from it's particular source-of-truth. +### Tracking Event + +A particular user action or application state representing a business objective or outcome, identified by a unique string, and recorded using the [tracking API](./sections/06-tracking.md). + ## Flagging specifics ```mermaid @@ -201,10 +205,6 @@ Pseudorandomly resolve flag values using a context property, such as a targeting A rule is some criteria that's used to determine which variant a particular context should be mapped to. -### Tracking Event - -A particular user action or application state representing a business objective or outcome, identified by a unique string, and recorded using the [tracking API](./sections/06-tracking.md). - ## SDK Paradigms Feature flag frameworks have SDKs which operate in two distinct paradigms: those designed for use with a single user client application (e.g. mobile phones, single-page web apps), and those designed for multi-user applications, such as web server applications. Some parts of the OpenFeature specification diverge depending on the paradigm. From 02164bc2d7a49a651b14a6436dafa4ef80348d7e Mon Sep 17 00:00:00 2001 From: Todd Baert Date: Wed, 2 Oct 2024 11:54:23 -0400 Subject: [PATCH 10/10] fixup: occurrence -> event Signed-off-by: Todd Baert --- specification.json | 2 +- specification/sections/02-providers.md | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/specification.json b/specification.json index cdd1a4f8..62147570 100644 --- a/specification.json +++ b/specification.json @@ -511,7 +511,7 @@ { "id": "Condition 2.7.1", "machine_id": "condition_2_7_1", - "content": "The `provider` MAY define a function for tracking the occurrence of a particular user action or application state, with parameters `occurrence key` (string, required), `evaluation context` (optional) and `occurrence details` (optional) which returns nothing.", + "content": "The `provider` MAY define a function for tracking the occurrence of a particular user action or application state, with parameters `tracking event name` (string, required), `evaluation context` (optional) and `tracking event details` (optional) which returns nothing.", "RFC 2119 keyword": "MAY", "children": [] }, diff --git a/specification/sections/02-providers.md b/specification/sections/02-providers.md index 90a90f96..31d7c51a 100644 --- a/specification/sections/02-providers.md +++ b/specification/sections/02-providers.md @@ -272,14 +272,14 @@ See [tracking](./06-tracking.md). #### Condition 2.7.1 -> The `provider` **MAY** define a function for tracking the occurrence of a particular user action or application state, with parameters `occurrence key` (string, required), `evaluation context` (optional) and `occurrence details` (optional) which returns nothing. +> The `provider` **MAY** define a function for tracking the occurrence of a particular user action or application state, with parameters `tracking event name` (string, required), `evaluation context` (optional) and `tracking event details` (optional) which returns nothing. ```java class MyProvider implements Tracking { //... /** - * Record a tracking occurrence. + * Record a tracking event. */ void track(String trackingEventName, EvaluationContext context, TrackingEventDetails details): void; @@ -288,7 +288,7 @@ class MyProvider implements Tracking { ``` The track function is a void function (function returning nothing). -The track function performs side effects required to record the `occurrence` in question, which may include network activity or other I/O; this I/O should not block the function call. +The track function performs side effects required to record the `tracking event` in question, which may include network activity or other I/O; this I/O should not block the function call. Providers should be careful to complete any communication or flush any relevant uncommitted tracking data before they shut down. See [shutdown](#25-shutdown). \ No newline at end of file