diff --git a/.gitignore b/.gitignore
index bcfc00e18..25d338527 100644
--- a/.gitignore
+++ b/.gitignore
@@ -14,4 +14,5 @@ go.work.sum
bin/
# built documentation
-site
\ No newline at end of file
+site
+.cache/
\ No newline at end of file
diff --git a/.gitmodules b/.gitmodules
index 643f35ec4..89959ef2f 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -4,3 +4,6 @@
[submodule "spec"]
path = spec
url = https://github.com/open-feature/spec.git
+[submodule "schemas"]
+ path = schemas
+ url = https://github.com/open-feature/schemas.git
diff --git a/.markdownlint-cli2.yaml b/.markdownlint-cli2.yaml
index fec47c686..9da958b1e 100644
--- a/.markdownlint-cli2.yaml
+++ b/.markdownlint-cli2.yaml
@@ -11,9 +11,14 @@ config:
- br
github-admonition: true
max-one-sentence-per-line: true
+ code-block-style: false # not compatible with mkdocs "details" panes
ignores:
- "**/CHANGELOG.md"
- "docs/specification"
- "node_modules"
- "tmp"
+ - "**/protos.md" # auto-generated
+ - "schemas" # submodule
+ - "spec" # submodule
+ - "test-harness" # submodule
diff --git a/Makefile b/Makefile
index d640b6082..1e8c0b941 100644
--- a/Makefile
+++ b/Makefile
@@ -9,6 +9,8 @@ ZD_CLIENT_IMG ?= zd-client:latest
FLAGD_PROXY_IMG ?= flagd-proxy:latest
FLAGD_PROXY_IMG_ZD ?= flagd-proxy:zd
+DOCS_DIR ?= web-docs
+
workspace-init: workspace-clean
go work init
$(foreach module, $(ALL_GO_MOD_DIRS), go work use $(module);)
@@ -105,4 +107,19 @@ markdownlint:
$(MDL_CMD) davidanson/markdownlint-cli2-rules:$(MDL_DOCKER_VERSION) "**/*.md"
markdownlint-fix:
- $(MDL_CMD) --entrypoint="markdownlint-cli2-fix" davidanson/markdownlint-cli2-rules:$(MDL_DOCKER_VERSION) "**/*.md"
\ No newline at end of file
+ $(MDL_CMD) --entrypoint="markdownlint-cli2-fix" davidanson/markdownlint-cli2-rules:$(MDL_DOCKER_VERSION) "**/*.md"
+
+.PHONY: pull-schemas-submodule
+pull-schemas-submodule:
+ git submodule update schemas
+
+.PHONY: generate-proto-docs
+generate-proto-docs: pull-schemas-submodule
+ docker run --rm -v ${PWD}/$(DOCS_DIR)/reference/specifications:/out -v ${PWD}/schemas/protobuf:/protos pseudomuto/protoc-gen-doc --doc_opt=markdown,protos-with-toc.md schema/v1/schema.proto sync/v1/sync_service.proto \
+ && echo '' > ${PWD}/$(DOCS_DIR)/reference/specifications/protos.md \
+ && sed '/^## Table of Contents/,/#top/d' ${PWD}/$(DOCS_DIR)/reference/specifications/protos-with-toc.md >> ${PWD}/$(DOCS_DIR)/reference/specifications/protos.md \
+ && rm -f ${PWD}/$(DOCS_DIR)/reference/specifications/protos-with-toc.md
+
+.PHONY: run-web-docs
+run-web-docs: generate-docs generate-proto-docs
+ docker run --rm -it -p 8000:8000 -v ${PWD}:/docs squidfunk/mkdocs-material
\ No newline at end of file
diff --git a/README.md b/README.md
index 62a8f132c..0d2dc9a59 100644
--- a/README.md
+++ b/README.md
@@ -21,7 +21,7 @@
## What's flagd?
-Flagd is a feature flag daemon with a Unix philosophy. Think of it as a ready-made, open source, OpenFeature compliant feature flag backend system.
+Flagd is a feature flag daemon with a Unix philosophy. Think of it as a ready-made, open source, OpenFeature-compliant feature flag backend system.
## Features
diff --git a/flagd/cmd/doc/main.go b/flagd/cmd/doc/main.go
index 8b909d31a..cc355c514 100644
--- a/flagd/cmd/doc/main.go
+++ b/flagd/cmd/doc/main.go
@@ -6,7 +6,7 @@ import (
"github.com/open-feature/flagd/flagd/cmd"
)
-const docPath = "../docs/configuration"
+const docPath = "../web-docs/reference/flagd-cli"
func main() {
if err := cmd.GenerateDoc(docPath); err != nil {
diff --git a/mkdocs.yml b/mkdocs.yml
index 4e29fe76c..474ee5714 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -1,4 +1,5 @@
site_name: flagd
+site_description: A feature flag daemon with a Unix philosophy
theme:
name: material
palette:
@@ -15,14 +16,14 @@ theme:
toggle:
icon: material/brightness-4
name: Switch to light mode
- # logo: path/to/file.png
- # favicon: path/to/file.png
+ logo: assets/logo-white.svg
+ favicon: assets/logo-white.svg
icon:
repo: fontawesome/brands/github
features:
- # - navigation.tabs
- - content.action.edit
- - content.code.copy
+ - navigation.footer
+ - content.action.edit
+ - content.code.copy
docs_dir: web-docs
repo_url: https://github.com/open-feature/flagd
@@ -32,27 +33,56 @@ markdown_extensions:
- pymdownx.highlight:
anchor_linenums: true
# linenums: true
+ line_spans: __span
+ pygments_lang_class: true
- pymdownx.inlinehilite
- pymdownx.snippets
- - pymdownx.superfences
+ - admonition
+ - pymdownx.details
+ - pymdownx.superfences:
+ custom_fences:
+ - name: mermaid
+ class: mermaid
+ format: !!python/name:pymdownx.superfences.fence_code_format
+ - tables
+ - attr_list
+ - pymdownx.emoji:
+ # we are using an older emoji extension because the newest (suggested in docs) doesn't work with Python < 3.10
+ emoji_index: !!python/name:materialx.emoji.twemoji
+ emoji_generator: !!python/name:materialx.emoji.to_svg
nav:
- - 'Home': 'index.md'
+ - 'Introduction': 'index.md'
+ - 'Quick start': 'quick-start.md'
- 'Concepts':
- - 'Flagd concepts (start here)': 'concepts/index.md'
- - 'Flagd architecture': 'concepts/architecture.md'
- - 'Flagd on Kubernetes':
- - 'Getting started with flagd on kubernetes': 'k8s/index.md'
- - 'Flagd outside of kubernetes':
- - 'Getting started with flagd outside of kubernetes': 'nonk8s/index.md'
- - 'Flag merging': 'nonk8s/flagmerging.md'
- - 'Flagd as a system service': 'nonk8s/systemservice.md'
- - 'Kubernetes Custom Resources':
- - 'FlagSourceConfiguration': 'k8s/crds/flagsourceconfiguration.md'
- - 'FeatureFlagConfiguration': 'k8s/crds/featureflagconfiguration.md'
- - 'Flagd Telemetry':
- - 'Flagd OpenTelemetry Support': 'concepts/opentelemetry.md'
+ - 'Feature Flagging': 'concepts/feature-flagging.md'
+ - 'Syncs': 'concepts/syncs.md'
+ - 'Architecture': 'architecture.md'
+ - 'Deployment': 'deployment.md'
+ - 'Reference':
+ - 'CLI':
+ - 'Commands': 'reference/flagd-cli/flagd.md'
+ - '"start" Command': 'reference/flagd-cli/flagd_start.md'
+ - '"version" Command': 'reference/flagd-cli/flagd/flagd_version.md'
+ - 'Sync Configuration': 'reference/sync-configuration.md'
+ - 'Flag Definitions':
+ - 'Definition Overview': 'reference/flag-definitions.md'
+ - 'Custom Operations':
+ - 'Fractional': 'reference/custom-operations/fractional-operation.md'
+ - 'Semantic Version': 'reference/custom-operations/semver-operation.md'
+ - 'String Comparison': 'reference/custom-operations/string-comparison-operation.md'
+ - 'Providers': 'reference/providers.md'
+ - 'Monitoring': 'reference/monitoring.md'
+ - 'Specifications':
+ - 'RPC Providers': 'reference/specifications/rpc-providers.md'
+ - 'In-Process Providers': 'reference/specifications/in-process-providers.md'
+ - 'Protobuf Schemas': 'reference/specifications/protos.md'
+ - 'Custom Operations':
+ - 'Fractional Specification': 'reference/specifications/custom-operations/fractional-operation-spec.md'
+ - 'Semantic Version Specification': 'reference/specifications/custom-operations/semver-operation-spec.md'
+ - 'String Comparison Specification': 'reference/specifications/custom-operations/string-comparison-operation-spec.md'
+ - 'Naming': 'reference/naming.md'
+ - 'FAQ': 'faq.md'
- 'Troubleshooting': 'troubleshooting.md'
- - 'Ecosystem and Tooling': 'ecosystem.md'
plugins:
- - social
\ No newline at end of file
+ - social
diff --git a/schemas b/schemas
new file mode 160000
index 000000000..f3e419c5e
--- /dev/null
+++ b/schemas
@@ -0,0 +1 @@
+Subproject commit f3e419c5ea676b6e0a4384b1ba3c9ad43b047eed
diff --git a/web-docs/concepts/architecture.md b/web-docs.old/concepts/architecture.md
similarity index 100%
rename from web-docs/concepts/architecture.md
rename to web-docs.old/concepts/architecture.md
diff --git a/web-docs/concepts/index.md b/web-docs.old/concepts/index.md
similarity index 100%
rename from web-docs/concepts/index.md
rename to web-docs.old/concepts/index.md
diff --git a/web-docs/concepts/opentelemetry.md b/web-docs.old/concepts/opentelemetry.md
similarity index 100%
rename from web-docs/concepts/opentelemetry.md
rename to web-docs.old/concepts/opentelemetry.md
diff --git a/web-docs/ecosystem.md b/web-docs.old/ecosystem.md
similarity index 100%
rename from web-docs/ecosystem.md
rename to web-docs.old/ecosystem.md
diff --git a/web-docs.old/images/flag-merge-1.svg b/web-docs.old/images/flag-merge-1.svg
new file mode 100644
index 000000000..0c6641ee6
--- /dev/null
+++ b/web-docs.old/images/flag-merge-1.svg
@@ -0,0 +1,17 @@
+
\ No newline at end of file
diff --git a/web-docs.old/images/flag-merge-2.svg b/web-docs.old/images/flag-merge-2.svg
new file mode 100644
index 000000000..6d91ecef6
--- /dev/null
+++ b/web-docs.old/images/flag-merge-2.svg
@@ -0,0 +1,17 @@
+
\ No newline at end of file
diff --git a/web-docs.old/images/flag-merge-3.svg b/web-docs.old/images/flag-merge-3.svg
new file mode 100644
index 000000000..a93354e02
--- /dev/null
+++ b/web-docs.old/images/flag-merge-3.svg
@@ -0,0 +1,17 @@
+
\ No newline at end of file
diff --git a/web-docs.old/images/flag-merge-4.svg b/web-docs.old/images/flag-merge-4.svg
new file mode 100644
index 000000000..02b7dd14e
--- /dev/null
+++ b/web-docs.old/images/flag-merge-4.svg
@@ -0,0 +1,17 @@
+
\ No newline at end of file
diff --git a/web-docs.old/images/flagd-logical-architecture.jpg b/web-docs.old/images/flagd-logical-architecture.jpg
new file mode 100644
index 000000000..e3a5c7147
Binary files /dev/null and b/web-docs.old/images/flagd-logical-architecture.jpg differ
diff --git a/web-docs.old/images/flagd-telemetry.png b/web-docs.old/images/flagd-telemetry.png
new file mode 100644
index 000000000..b4182b506
Binary files /dev/null and b/web-docs.old/images/flagd-telemetry.png differ
diff --git a/web-docs.old/images/of-flagd-0.png b/web-docs.old/images/of-flagd-0.png
new file mode 100644
index 000000000..a910f0b4e
Binary files /dev/null and b/web-docs.old/images/of-flagd-0.png differ
diff --git a/web-docs.old/images/of-flagd-1.png b/web-docs.old/images/of-flagd-1.png
new file mode 100644
index 000000000..5e059fcb1
Binary files /dev/null and b/web-docs.old/images/of-flagd-1.png differ
diff --git a/web-docs.old/index.md b/web-docs.old/index.md
new file mode 100644
index 000000000..78c5e9d63
--- /dev/null
+++ b/web-docs.old/index.md
@@ -0,0 +1,30 @@
+# flagd
+
+Flagd is a feature flag daemon. It is a ready-made, open source, [OpenFeature](https://openfeature.dev) compliant feature flag backend system.
+
+- OpenFeature compliant and speaks your language.
+- Easy to extend to new languages.
+- Supports multiple data sources simultaneously.
+- Feature Flag updates occur in near real-time.
+- Contains a powerful and flexible rule targeting engine and deterministic percentage-based rollouts.
+- Flag evaluation statistics and metrics are exposed and compatible with OpenTelemetry.
+
+![flagd architecture](images/flagd-logical-architecture.jpg)
+
+## flagd concepts
+
+Whether you choose to run flagd on a Kubernetes cluster or outside of Kubernetes, there are concepts that apply to both equally.
+
+Start your flagd learning journey here: [flagd concepts](concepts/index.md)
+
+## Running flagd
+
+### Kubernetes or Non-Kubernetes?
+
+Now that you know the concepts, it's time to decide how to run flagd.
+
+flagd can run on Kubernetes and in non-k8s environments.
+Choose your mode of deployment to learn more:
+
+- [flagd on Kubernetes](k8s/index.md)
+- [flagd running outside of Kubernetes](nonk8s/index.md)
diff --git a/web-docs/k8s/crds/featureflagconfiguration.md b/web-docs.old/k8s/crds/featureflagconfiguration.md
similarity index 100%
rename from web-docs/k8s/crds/featureflagconfiguration.md
rename to web-docs.old/k8s/crds/featureflagconfiguration.md
diff --git a/web-docs/k8s/crds/flagsourceconfiguration.md b/web-docs.old/k8s/crds/flagsourceconfiguration.md
similarity index 100%
rename from web-docs/k8s/crds/flagsourceconfiguration.md
rename to web-docs.old/k8s/crds/flagsourceconfiguration.md
diff --git a/web-docs/k8s/index.md b/web-docs.old/k8s/index.md
similarity index 100%
rename from web-docs/k8s/index.md
rename to web-docs.old/k8s/index.md
diff --git a/web-docs/nonk8s/flagmerging.md b/web-docs.old/nonk8s/flagmerging.md
similarity index 100%
rename from web-docs/nonk8s/flagmerging.md
rename to web-docs.old/nonk8s/flagmerging.md
diff --git a/web-docs/nonk8s/index.md b/web-docs.old/nonk8s/index.md
similarity index 100%
rename from web-docs/nonk8s/index.md
rename to web-docs.old/nonk8s/index.md
diff --git a/web-docs/nonk8s/systemservice.md b/web-docs.old/nonk8s/systemservice.md
similarity index 100%
rename from web-docs/nonk8s/systemservice.md
rename to web-docs.old/nonk8s/systemservice.md
diff --git a/web-docs.old/troubleshooting.md b/web-docs.old/troubleshooting.md
new file mode 100644
index 000000000..7d99a8f1a
--- /dev/null
+++ b/web-docs.old/troubleshooting.md
@@ -0,0 +1,32 @@
+# Troubleshooting flagd
+
+## HTTP(S) Service Integer Response Behavior
+
+Why is my `int` response a `string`?
+Command:
+
+```sh
+curl -X POST "localhost:8013/schema.v1.Service/ResolveInt" -d '{"flagKey":"myIntFlag","context":{}}' -H "Content-Type: application/json"
+```
+
+Result:
+
+```sh
+{"value":"1","reason":"DEFAULT","variant":"one"}
+```
+
+When interacting directly with the flagD http(s) api and requesting an `int` the response type will be a `string`.
+This behaviour is introduced by [grpc-gateway](https://github.com/grpc-ecosystem/grpc-gateway), which uses [proto3 json mapping](https://developers.google.com/protocol-buffers/docs/proto3#json) to build the response object.
+If a number value is required, and none of the provided SDK's can be used, then it is recommended to use the `float64` endpoint instead:
+
+Command:
+
+```sh
+curl -X POST "localhost:8013/schema.v1.Service/ResolveFloat" -d '{"flagKey":"myIntFlag","context":{}}' -H "Content-Type: application/json"
+```
+
+Result:
+
+```sh
+{"value":1.23,"reason":"DEFAULT","variant":"one"}
+```
diff --git a/web-docs/architecture.md b/web-docs/architecture.md
new file mode 100644
index 000000000..852cb3f6a
--- /dev/null
+++ b/web-docs/architecture.md
@@ -0,0 +1,45 @@
+# Architecture
+
+flagd architectures fall into two broad categories: those where the evaluation engine is deployed in a standalone process to which the client application connects ([RPC](#rpc-evaluation)), and those where the evaluation engine is embedded into the client application ([in-process](#in-process-evaluation)).
+
+## RPC vs In-Process Evaluation
+
+### RPC evaluation
+
+In RPC-based deployments one or more flagd instances deployed and exposed to client applications in your infrastructure.
+flagd RPC providers use HTTP or gRPC to request flag evaluations from flagd.
+The request payload contains the [flag key](https://openfeature.dev/specification/glossary#flag-key) identifying the flag to be evaluated, as well as the relevant [evaluation context](https://openfeature.dev/specification/glossary#evaluation-context).
+The flagd instance is configured to watch one or more [syncs](./concepts/syncs.md), and merges them to build its set of flags (see [here](./concepts/syncs.md#merging) for more details on flag definition merging).
+When sync sources are updated, flagd will send notifications to clients that flags have changed, enabling applications to react to changes by re-evaluating flags.
+
+This architecture is can be leveraged by very simple clients, since no in-process engine is needed; in fact, you can evaluate flags directly from a terminal console using the `cURL` utility.
+One disadvantage of this pattern is the latency involved in the remote request (though flagd typically takes <10ms for an evaluation, and can evaluate thousands of flags per second).
+
+```mermaid
+---
+title: RPC Evaluation
+---
+erDiagram
+ flagd ||--o{ "sync (file)" : watches
+ flagd ||--o{ "sync (http)" : polls
+ flagd ||--o{ "sync (grpc)" : "sync.proto (gRPC/stream)"
+ flagd ||--o{ "sync (kubernetes)" : watches
+ "client app (+ flagd RPC provider)" ||--|| flagd : "evaluation.proto (gRPC/stream) / HTTP"
+```
+
+### In-Process evaluation
+
+In-process deployments embed the flagd evaluation engine directly into the client application through the use of an [in-process provider](./deployment.md#in-process).
+The in-process provider is connected via the sync protocol to an implementing [gRPC service](./concepts/syncs.md#grpc-sync) that provides the flag definitions.
+This pattern requires an in-process implementation of the flagd evaluation engine, but has the benefit of no I/O overhead, since no inter-process communication is required.
+
+```mermaid
+---
+title: In-Process Evaluation
+---
+erDiagram
+ "client app (+ flagd in-process provider)" ||--|| "sync (grpc)" : "sync.proto (gRPC/stream)"
+```
+
+
+
\ No newline at end of file
diff --git a/web-docs/assets/demo.flagd.json b/web-docs/assets/demo.flagd.json
new file mode 100644
index 000000000..e61619133
--- /dev/null
+++ b/web-docs/assets/demo.flagd.json
@@ -0,0 +1,22 @@
+{
+ "flags": {
+ "show-welcome-banner": {
+ "state": "ENABLED",
+ "variants": {
+ "on": true,
+ "off": false
+ },
+ "defaultVariant": "off"
+ },
+ "background-color": {
+ "state": "ENABLED",
+ "variants": {
+ "red": "#FF0000",
+ "blue": "#0000FF",
+ "green": "#00FF00",
+ "yellow": "#FFFF00"
+ },
+ "defaultVariant": "red"
+ }
+ }
+}
\ No newline at end of file
diff --git a/web-docs/assets/logo-white.svg b/web-docs/assets/logo-white.svg
new file mode 100644
index 000000000..dbbf98e32
--- /dev/null
+++ b/web-docs/assets/logo-white.svg
@@ -0,0 +1,10 @@
+
diff --git a/web-docs/concepts/feature-flagging.md b/web-docs/concepts/feature-flagging.md
new file mode 100644
index 000000000..60437395e
--- /dev/null
+++ b/web-docs/concepts/feature-flagging.md
@@ -0,0 +1,24 @@
+# Feature Flagging
+
+Feature flags are a software development technique that allows teams to enable, disable or change the behavior of certain features or code paths in a product or service, without modifying the source code.
+
+## OpenFeature Compliance
+
+[OpenFeature](https://openfeature.dev/) is an open standard that provides a vendor-agnostic, community-driven API for feature flagging.
+The flagd project is fully OpenFeature-compliant.
+In fact, flagd was initially conceived as a reference implementation for an OpenFeature backend, but has become a powerful tool in its own right.
+For this reason, you'll find flagd's concepts and terminology align with that of the OpenFeature project.
+Within the context of an OpenFeature-compliant feature flag solution, flagd artifacts and libraries comprise the [flag management system](https://openfeature.dev/specification/glossary#flag-management-system) and [providers](https://openfeature.dev/specification/glossary#provider).
+These artifacts and libraries alone won't allow you to evaluate flags in your application - you'll also need the [OpenFeature SDK](https://openfeature.dev/specification/glossary#feature-flag-sdk) for your language as well, which provides the evaluation API for application developers to use.
+
+## Supported Feature Flagging Use-Cases
+
+Below is a non-exhaustive table of common feature flag use-cases, and how flagd supports them:
+
+| Use case | flagd Feature |
+| ----------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| flag evaluation | Returns the value of a particular feature flag, if the flag is enabled. Supports flags of various types including boolean, numeric, string, and JSON. |
+| dynamic configuration | Flag definitions from any sync source are monitored for changes, with some syncs supporting near real time updates. |
+| dynamic (context-sensitive) evaluation | flagd evaluations are context sensitive. Rules can use arbitrary context attributes as inputs for flag evaluation logic. |
+| fractional evaluation / random assignment | flagd's [fractional](../reference/custom-operations/fractional-operation.md) custom operation supports pseudorandom assignment of flag values. |
+| progressive roll-outs | Progressive roll-outs of new features can be accomplished by leveraging the [fractional](../reference/custom-operations/fractional-operation.md) custom operation as well as automation in your build pipeline, SCM, or infrastructure which updates the distribution over time. |
diff --git a/web-docs/concepts/syncs.md b/web-docs/concepts/syncs.md
new file mode 100644
index 000000000..21d1ada3b
--- /dev/null
+++ b/web-docs/concepts/syncs.md
@@ -0,0 +1,114 @@
+# Syncs
+
+Syncs are a core part of flagd; they are the abstraction that enables different sources for feature flag definitions.
+flagd can connect to one or more sync sources to
+
+## Available syncs
+
+### Filepath sync
+
+The file path sync provider reads and watch the source file for updates(ex: changes and deletions).
+
+```shell
+flagd start --uri file:etc/featureflags.json
+```
+
+In this example, `etc/featureflags.json` is a valid feature flag definition file accessible by the flagd process.
+See [sync source](../reference/sync-configuration.md#source-configuration) configuration for details.
+
+---
+
+### HTTP sync
+
+The HTTP sync provider fetch flags from a remote source and periodically poll the source for flag definition updates.
+
+```shell
+flagd start --uri https://my-flag-source.json
+```
+
+In this example, `https://my-flag-source.json` is a remote endpoint responding valid feature flag definition when
+invoked with **HTTP GET** request.
+The polling interval, port, TLS settings, and authentication information can be configured.
+See [sync source](../reference/sync-configuration.md#source-configuration) configuration for details.
+
+---
+
+### gRPC sync
+
+The gRPC sync provider streams flag definition from a gRPC sync provider implementation. This stream connection is ruled
+by
+the [sync service protobuf definition](https://github.com/open-feature/schemas/blob/main/protobuf/sync/v1/sync_service.proto).
+
+```shell
+flagd start --uri grpc://grpc-sync-source
+```
+
+In this example, `grpc-sync-source` is a grpc target implementing [sync.proto](../reference/flag-sync-protocol.md) definition.
+See [sync source](../reference/sync-configuration.md#source-configuration) configuration for details.
+
+---
+
+### Kubernetes sync
+
+The Kubernetes sync provider allows flagd to connect to a Kubernetes cluster and evaluate flags against a specified
+FeatureFlagConfiguration resource as defined within
+the [open-feature-operator](https://github.com/open-feature/open-feature-operator/blob/main/apis/core/v1alpha1/featureflagconfiguration_types.go)
+spec.
+This configuration is best used in conjunction with the [OpenFeature Operator](https://github.com/open-feature/open-feature-operator).
+
+To use an existing FeatureFlagConfiguration custom resource, start flagD with the following command:
+
+```shell
+flagd start --uri core.openfeature.dev/default/my_example
+```
+
+In this example, `default/my_example` expected to be a valid FeatureFlagConfiguration resource, where `default` is the
+namespace and `my_example` being the resource name.
+See [sync source](../reference/sync-configuration.md#source-configuration) configuration for details.
+
+## Merging
+
+Flagd can be configured to read from multiple sources at once, when this is the case flagd will merge all flag definition into a single
+merged state.
+
+For example:
+
+![flag merge 1](../images/flag-merge-1.svg)
+
+In this example, `source-A` and `source-B` provide a single flag definition, the `foo` flag and the `bar` flag respectively.
+The merge logic for this definition is simple, both flag definition are added to the `store`.
+
+In most scenarios, these flag sources will be supplying `n` number of definition, using a unique flag key for each definition.
+
+However, as multiple sources are being used, there is the opportunity for keys to be duplicated, intentionally or not, between flag sources.
+In these situations `flagd` uses a merge priority order to ensure that its behavior is consistent.
+
+Merge order is dictated by the order that `sync-providers` and `uris` are defined, with the latest defined source taking precedence over those defined before it, as an example:
+
+```sh
+./bin/flagd start --uri file:source-A.json --uri file:source-B.json --uri file:source-C.json
+```
+
+When `flagd` is started with the command defined above, `source-B` takes priority over `source-A`, whilst `source-C` takes priority over both `source-B` and `source-A`.
+
+Using the above example, if a flag key is duplicated across all 3 sources, then the definition from `source-C` would be the only one stored in the merged state.
+
+![flag merge 2](../images/flag-merge-2.svg)
+
+### State Resync Events
+
+Given the above example, the `source-A` and `source-B` 'versions' of flag definition the `foo` have been discarded, so if a delete event in `source-C` results in the removal of the `foo`flag, there will no longer be any reference of `foo` in flagd's store.
+
+As a result of this flagd will return `FLAG_NOT_FOUND` errors, and the OpenFeature SDK will always return the default value.
+
+To prevent flagd falling out of sync with its flag sources during delete events, resync events are used.
+When a delete event results in a flag definition being removed from the merged state, the full set of definition is requested from all flag sources, and the merged state is rebuilt.
+As a result, the value of the `foo` flag from `source-B` will be stored in the merged state, preventing flagd from returning `FLAG_NOT_FOUND` errors.
+
+![flag merge 3](../images/flag-merge-3.svg)
+
+In the example above, a delete event results in a resync event being fired, as `source-C` has deleted its 'version' of the `foo`, this results in a new merge state being formed from the remaining definition.
+
+![flag merge 4](../images/flag-merge-4.svg)
+
+Resync events may lead to further resync events if the returned flag definition result in further delete events, however the state will eventually be resolved correctly.
diff --git a/web-docs/deployment.md b/web-docs/deployment.md
new file mode 100644
index 000000000..74e6548bf
--- /dev/null
+++ b/web-docs/deployment.md
@@ -0,0 +1,64 @@
+# Deployment
+
+## Docker
+
+:octicons-terminal-24: Install from the command line:
+
+```shell
+docker pull ghcr.io/open-feature/flagd:latest
+```
+
+:octicons-code-square-24: Use as base image in Dockerfile:
+
+```dockerfile
+FROM ghcr.io/open-feature/flagd:latest
+```
+
+### Kubernetes
+
+flagd was designed with cloud-native paradigms in mind.
+You can run it as a sidecar, or as a central service in your cluster.
+If you're interested in a full-featured solution for using flagd in Kubernetes, consider the [OpenFeature operator](https://github.com/open-feature/open-feature-operator).
+
+
+
+---
+
+## Binary
+
+:fontawesome-brands-linux::fontawesome-brands-windows::fontawesome-brands-apple: Binaries are available in x86/ARM.
+
+[Release](https://github.com/open-feature/flagd/releases)
+
+### systemd
+
+A systemd wrapper is available [here](https://github.com/open-feature/flagd/blob/main/systemd/flagd.service).
+
+---
+
+## In-Process
+
+### :fontawesome-brands-golang: Go in-process provider
+
+[flagd-in-process/pkg](https://pkg.go.dev/github.com/open-feature/go-sdk-contrib/providers/flagd-in-process/pkg)
+
+```shell
+go get github.com/open-feature/go-sdk-contrib/providers/flagd-in-process/pkg@v0.1.1
+```
+
+### :fontawesome-brands-java: Java in-process provider
+
+#### Maven
+
+```xml
+
+ dev.openfeature.contrib.providers
+ flagd
+
+```
+
+#### Gradle
+
+```gradle
+implementation 'dev.openfeature.contrib.providers:flagd'
+```
diff --git a/web-docs/faq.md b/web-docs/faq.md
new file mode 100644
index 000000000..1afd48f35
--- /dev/null
+++ b/web-docs/faq.md
@@ -0,0 +1,37 @@
+# Frequently Asked Questions
+
+> Why do I need this? Can't I just use environment variables?
+
+Feature flags are not environment variables.
+If you need to update your flag values without restarting your application, target specific users, randomly assign values for experimentation, or perform scheduled roll-outs, you should consider using feature flags.
+If the values are always static, an environment variable or static configuration may be sufficient.
+
+For more information on feature-flagging concepts, see [feature-flagging](./concepts/feature-flagging.md).
+
+---
+
+> Why is it called "flagd"?
+
+Please see [naming](./reference/naming.md).
+
+---
+
+> What is flagd's relationship to OpenFeature?
+
+flagd is sub-project of OpenFeature and aims to be fully [OpenFeature-compliant](./concepts/feature-flagging.md#openfeature-compliance).
+
+---
+
+> How do I run flagd?
+
+You can run flagd as a standalone application, accessible over HTTP or gRPC, or you can embed it into your application.
+Please see [architecture](./architecture.md) and [deployment](./deployment.md) for more information.
+
+---
+
+> Why doesn't flagd support {_my desired feature_}?
+
+Because you haven't opened a PR or created an issue!
+
+We're always adding new functionality to flagd, and welcome additions and ideas from new contributors.
+Don't hesitate to [open an issue](https://github.com/open-feature/flagd/issues)!
diff --git a/web-docs/index.md b/web-docs/index.md
index 78c5e9d63..7a1c4744d 100644
--- a/web-docs/index.md
+++ b/web-docs/index.md
@@ -1,30 +1,40 @@
-# flagd
+# Introduction
-Flagd is a feature flag daemon. It is a ready-made, open source, [OpenFeature](https://openfeature.dev) compliant feature flag backend system.
+## What is flagd?
-- OpenFeature compliant and speaks your language.
-- Easy to extend to new languages.
-- Supports multiple data sources simultaneously.
-- Feature Flag updates occur in near real-time.
-- Contains a powerful and flexible rule targeting engine and deterministic percentage-based rollouts.
-- Flag evaluation statistics and metrics are exposed and compatible with OpenTelemetry.
+_flagd_ is a _feature flag evaluation engine_.
+Think of it as a ready-made, open source, OpenFeature-compliant feature flag backend system.
-![flagd architecture](images/flagd-logical-architecture.jpg)
+With flagd you can:
-## flagd concepts
+* modify flags in real time
+* define flags of various types (boolean, string, number, JSON)
+* use context-sensitive rules to target specific users or user-traits
+* perform pseudorandom assignments for experimentation
+* perform progressive roll-outs of new features
+* aggregate flag definitions from multiple sources
-Whether you choose to run flagd on a Kubernetes cluster or outside of Kubernetes, there are concepts that apply to both equally.
+It doesn't include a UI, management console or a persistence layer.
+It's configurable entirely via a POSIX-style CLI.
+Thanks to it's minimalism, it's _extremely flexible_; you can leverage flagd as a sidecar alongside your application, an engine running in your application process, or as a central service evaluating thousands of flags per second.
-Start your flagd learning journey here: [flagd concepts](concepts/index.md)
+## How do I deploy flagd?
-## Running flagd
+flagd is designed to fit well into a variety of infrastructures, and can run on various architectures.
+It run as a separate process or directly in your application.
+It's distributed as a binary, container image, and various libraries.
+If you're already leveraging containers in your infrastructure, you can extend the docker image with your required configuration.
+You can also run flagd as a service on a VM or a "bare-metal" host.
+If you'd prefer not to run an additional process at all, you can run the flagd evaluation engine directly in your application.
+No matter how you run flagd, you will need to supply it with feature flags.
+The flag definitions supplied to flagd (_sources_) are monitored for changes which will be immediately reflected in flagd's evaluations.
+Currently supported sources include files, HTTP endpoints, Kubernetes custom resources, and proto-compliant gRPC services.
-### Kubernetes or Non-Kubernetes?
+
-Now that you know the concepts, it's time to decide how to run flagd.
+## How do I use flagd?
-flagd can run on Kubernetes and in non-k8s environments.
-Choose your mode of deployment to learn more:
-
-- [flagd on Kubernetes](k8s/index.md)
-- [flagd running outside of Kubernetes](nonk8s/index.md)
+flagd is fully OpenFeature compliant.
+To leverage it in your application you must use the OpenFeature SDK and flagd provider for your language.
+You can configure the provider to connect to a flagd instance you deployed earlier (evaluating flags over gRPC) or use the in-process evaluation engine to do flag evaluations directly in your application.
+Once you've configured the OpenFeature SDK, you can start evaluating the feature flags configured in your flagd definitions.
diff --git a/web-docs/quick-start.md b/web-docs/quick-start.md
new file mode 100644
index 000000000..fc97ec4db
--- /dev/null
+++ b/web-docs/quick-start.md
@@ -0,0 +1,214 @@
+---
+name: Quick Start
+---
+
+# Quick Start
+
+Learn the basics of flagd from the comfort of your terminal.
+
+## What you'll need
+
+- Docker
+- cURL
+
+## Let's get started
+
+### Download the flag definition
+
+```shell
+wget https://raw.githubusercontent.com/open-feature/flagd/main/web-docs/assets/demo.flagd.json
+```
+
+The flag definition file includes two feature flags.
+The first one has the flag key `show-welcome-banner` and is a boolean type.
+These types of feature flags are commonly used gate access to a new feature using a conditional in code.
+The second flag has the key `background-color` and is a multi-variant string.
+These are commonly used for A/B/(n) testing and experimentation.
+
+### Start flagd
+
+```shell
+docker run \
+ --rm -it \
+ --name flagd \
+ -p 8013:8013 \
+ -v $(pwd):/etc/flagd \
+ ghcr.io/open-feature/flagd:latest start \
+ --uri file:./etc/flagd/demo.flagd.json
+```
+
+??? "Tips for Windows users"
+ In Windows, use WSL system for both the file location and Docker runtime.
+ Mixed file systems does not work and this is a [limitation of Docker](https://github.com/docker/for-win/issues/8479).
+
+### Evaluating a feature flag
+
+Test it out
+
+```shell
+curl -X POST "http://localhost:8013/schema.v1.Service/ResolveBoolean" \
+ -d '{"flagKey":"show-welcome-banner","context":{}}' -H "Content-Type: application/json"
+```
+
+You should see the following result:
+
+```json
+{
+ "value": false,
+ "reason": "STATIC",
+ "variant": "off",
+ "metadata": {}
+}
+```
+
+### Enable the welcome banner
+
+Open the `demo.flagd.json` file in a text editor and change the `defaultVariant` value from `off` to `on`.
+
+Save and rerun the following cURL command:
+
+```shell
+curl -X POST "http://localhost:8013/schema.v1.Service/ResolveBoolean" \
+ -d '{"flagKey":"show-welcome-banner","context":{}}' -H "Content-Type: application/json"
+```
+
+You should see the updated results:
+
+```json
+{
+ "value": true,
+ "reason": "STATIC",
+ "variant": "on",
+ "metadata": {}
+}
+```
+
+!!! note ""
+
+ Notice that flagd picked up the new flag definition without requiring a restart.
+
+### Multi-variant feature flags
+
+In some situations, a boolean value may not be enough.
+That's where a multi-variant feature flag comes in handy.
+In this section, we'll talk about a multi-variant feature flag can be used to control the background color of an application.
+
+Save and rerun the following cURL command:
+
+```shell
+curl -X POST "http://localhost:8013/schema.v1.Service/ResolveString" \
+ -d '{"flagKey":"background-color","context":{}}' -H "Content-Type: application/json"
+```
+
+You should see the updated results:
+
+```json
+{
+ "value": "#FF0000",
+ "reason": "STATIC",
+ "variant": "red",
+ "metadata": {}
+}
+```
+
+### Add a targeting rule
+
+Imagine that we're testing out a new color scheme internally.
+Employees should see the green background color while customers should continue seeing red.
+This can be accomplished in flagd using targeting rules.
+
+Open the `demo.flagd.json` file in a text editor and extend the `background-color` to include a targeting rule.
+
+``` json hl_lines="19-32"
+{
+ "flags": {
+ "show-welcome-banner": {
+ "state": "ENABLED",
+ "variants": {
+ "on": true,
+ "off": false
+ },
+ "defaultVariant": "off"
+ },
+ "background-color": {
+ "state": "ENABLED",
+ "variants": {
+ "red": "#FF0000",
+ "blue": "#0000FF",
+ "green": "#00FF00",
+ "yellow": "#FFFF00"
+ },
+ "defaultVariant": "red",
+ "targeting": {
+ "if": [
+ {
+ "===": [
+ {
+ "var": "company"
+ },
+ "initech"
+ ]
+ },
+ "green"
+ ]
+ }
+ }
+ }
+}
+```
+
+The evaluation context contains arbitrary attributes that targeting rules can operate on, and can be included in each feature flag evaluation.
+This rule will return the `green` variant if the `company` included in the _evaluation context_ matches `initech`.
+If there isn't a match, the `defaultVariant` is returned.
+
+#### Test as a customer
+
+Let's confirm that customers are still seeing the `red` variant.
+
+```shell
+curl -X POST "http://localhost:8013/schema.v1.Service/ResolveString" \
+ -d '{"flagKey":"background-color","context":{"company": "stark industries"}}' -H "Content-Type: application/json"
+```
+
+You should see the updated results:
+
+```json
+{
+ "value": "#FF0000",
+ "reason": "DEFAULT",
+ "variant": "red",
+ "metadata": {}
+}
+```
+
+#### Test as an employee
+
+Let's confirm that employees of Initech are seeing the updated variant.
+
+Run the following cURL command in the terminal.
+
+```shell
+curl -X POST "http://localhost:8013/schema.v1.Service/ResolveString" \
+ -d '{"flagKey":"background-color","context":{"company": "initech"}}' -H "Content-Type: application/json"
+```
+
+You should see the updated results:
+
+```json
+{
+ "value": "#00FF00",
+ "reason": "TARGETING_MATCH",
+ "variant": "green",
+ "metadata": {}
+}
+```
+
+Notice that the `green` variant is returned and the reason is `TARGETING_MATCH`.
+
+## Summary
+
+In this guide, we configured flagd to use a local flag configuration.
+We then performed flag evaluation using cURL to see how updating the flag definition affects the output.
+We also explored how evaluation context can be used within a targeting rule to personalize the output.
+This is just scratching the surface of flagd's capabilities.
+Check out the [concepts section](./concepts//feature-flagging.md) to learn about the use cases enabled by flagd.
diff --git a/web-docs/reference/custom-operations/fractional-operation.md b/web-docs/reference/custom-operations/fractional-operation.md
new file mode 100644
index 000000000..f148a4e3e
--- /dev/null
+++ b/web-docs/reference/custom-operations/fractional-operation.md
@@ -0,0 +1,138 @@
+# Fractional Operation
+
+OpenFeature allows clients to pass contextual information which can then be used during a flag evaluation. For example, a client could pass the email address of the user.
+
+```js
+// Factional evaluation property name used in a targeting rule
+"fractional": [
+ // Evaluation context property used to determine the split
+ { "var": "email" },
+ // Split definitions contain an array with a variant and percentage
+ // Percentages must add up to 100
+ [
+ // Must match a variant defined in the flag definition
+ "red",
+ // The probability this variant is selected
+ 50
+ ],
+ [
+ // Must match a variant defined in the flag definition
+ "green",
+ // The probability this variant is selected
+ 50
+ ]
+]
+```
+
+See the [headerColor](https://github.com/open-feature/flagd/blob/main/samples/example_flags.flagd.json#L88-#L133) flag.
+The `defaultVariant` is `red`, but it contains a [targeting rule](reusable_targeting_rules.md), meaning a fractional evaluation occurs for flag evaluation with a `context` object containing `email` and where that `email` value contains `@faas.com`.
+
+In this case, `25%` of the evaluations will receive `red`, `25%` will receive `blue`, and so on.
+
+Assignment is deterministic (sticky) based on the expression supplied as the first parameter (`{ "var": "email" }`, in this case).
+The value retrieved by this expression is referred to as the "bucketing value".
+The bucketing value expression can be omitted, in which case a concatenation of the `targetingKey` and the `flagKey` will be used.
+
+The `fractional` operation is a custom JsonLogic operation which deterministically selects a variant based on
+the defined distribution of each variant (as a percentage).
+This works by hashing ([murmur3](https://github.com/aappleby/smhasher/blob/master/src/MurmurHash3.cpp))
+the given data point, converting it into an int in the range [0, 99].
+Whichever range this int falls in decides which variant
+is selected.
+As hashing is deterministic we can be sure to get the same result every time for the same data point.
+
+The `fractional` operation can be added as part of a targeting definition.
+The value is an array and the first element is the name of the property to use from the evaluation context.
+This value should typically be something that remains consistent for the duration of a users session (e.g. email or session ID).
+The other elements in the array are nested arrays with the first element representing a variant and the second being the percentage that this option is selected.
+There is no limit to the number of elements but the configured percentages must add up to 100.
+
+## Example
+
+Flags defined as such:
+
+```json
+{
+ "flags": {
+ "headerColor": {
+ "variants": {
+ "red": "#FF0000",
+ "blue": "#0000FF",
+ "green": "#00FF00"
+ },
+ "defaultVariant": "red",
+ "state": "ENABLED",
+ "targeting": {
+ "fractional": [
+ { "var": "email" },
+ [
+ "red",
+ 50
+ ],
+ [
+ "blue",
+ 20
+ ],
+ [
+ "green",
+ 30
+ ]
+ ]
+ }
+ }
+ }
+}
+```
+
+will return variant `red` 50% of the time, `blue` 20% of the time & `green` 30% of the time.
+
+Command:
+
+```shell
+curl -X POST "localhost:8013/schema.v1.Service/ResolveString" -d '{"flagKey":"headerColor","context":{"email": "foo@bar.com"}}' -H "Content-Type: application/json"
+```
+
+Result:
+
+```shell
+{"value":"#0000FF","reason":"TARGETING_MATCH","variant":"blue"}
+```
+
+Command:
+
+```shell
+curl -X POST "localhost:8013/schema.v1.Service/ResolveString" -d '{"flagKey":"headerColor","context":{"email": "foo@test.com"}}' -H "Content-Type: application/json"
+```
+
+Result:
+
+```json
+{"value":"#00FF00","reason":"TARGETING_MATCH","variant":"green"}
+```
+
+Notice that rerunning either curl command will always return the same variant and value.
+The only way to get a different value is to change the email or update the `fractional` configuration.
+
+### Migrating from legacy "fractionalEvaluation"
+
+If you are using a legacy fractional evaluation (`fractionalEvaluation`), it's recommended you migrate to `fractional`.
+The new `fractional` evaluator supports nested properties and JsonLogic expressions.
+To migrate, simply use a JsonLogic variable declaration for the bucketing property, instead of a string:
+
+old:
+
+```json
+"fractionalEvaluation": [
+ "email",
+ [ "red", 25 ], [ "blue", 25 ], [ "green", 25 ], [ "yellow", 25 ]
+]
+```
+
+new:
+
+```json
+"fractional": [
+ { "var": "email" },
+ [ "red", 25 ], [ "blue", 25 ], [ "green", 25 ], [ "yellow", 25 ]
+]
+```
diff --git a/web-docs/reference/custom-operations/semver-operation.md b/web-docs/reference/custom-operations/semver-operation.md
new file mode 100644
index 000000000..6c821c51b
--- /dev/null
+++ b/web-docs/reference/custom-operations/semver-operation.md
@@ -0,0 +1,80 @@
+# Semantic Version Operation
+
+OpenFeature allows clients to pass contextual information which can then be used during a flag evaluation. For example, a client could pass the email address of the user.
+
+In some scenarios, it is desirable to use that contextual information to segment the user population further and thus return dynamic values.
+
+The `sem_ver` evaluation checks if the given property matches a semantic versioning condition.
+It returns 'true', if the value of the given property meets the condition, 'false' if not.
+Note that the 'sem_ver' evaluation rule must contain exactly three items:
+
+1. Target property: this needs which both resolve to a semantic versioning string
+2. Operator: One of the following: `=`, `!=`, `>`, `<`, `>=`, `<=`, `~` (match minor version), `^` (match major version)
+3. Target value: this needs which both resolve to a semantic versioning string
+
+The `sem_ver` evaluation returns a boolean, indicating whether the condition has been met.
+
+```js
+{
+ "if": [
+ {
+ "sem_ver": [{"var": "version"}, ">=", "1.0.0"]
+ },
+ "red", null
+ ]
+}
+```
+
+## Example for 'sem_ver' Evaluation
+
+Flags defined as such:
+
+```json
+{
+ "flags": {
+ "headerColor": {
+ "variants": {
+ "red": "#FF0000",
+ "blue": "#0000FF",
+ "green": "#00FF00"
+ },
+ "defaultVariant": "blue",
+ "state": "ENABLED",
+ "targeting": {
+ "if": [
+ {
+ "sem_ver": [{"var": "version"}, ">=", "1.0.0"]
+ },
+ "red", "green"
+ ]
+ }
+ }
+ }
+}
+```
+
+will return variant `red`, if the value of the `version` is a semantic version that is greater than or equal to `1.0.0`.
+
+Command:
+
+```shell
+curl -X POST "localhost:8013/schema.v1.Service/ResolveString" -d '{"flagKey":"headerColor","context":{"version": "1.0.1"}}' -H "Content-Type: application/json"
+```
+
+Result:
+
+```json
+{"value":"#00FF00","reason":"TARGETING_MATCH","variant":"red"}
+```
+
+Command:
+
+```shell
+curl -X POST "localhost:8013/schema.v1.Service/ResolveString" -d '{"flagKey":"headerColor","context":{"version": "0.1.0"}}' -H "Content-Type: application/json"
+```
+
+Result:
+
+```shell
+{"value":"#0000FF","reason":"TARGETING_MATCH","variant":"green"}
+```
diff --git a/web-docs/reference/custom-operations/string-comparison-operation.md b/web-docs/reference/custom-operations/string-comparison-operation.md
new file mode 100644
index 000000000..6e6eb9fdc
--- /dev/null
+++ b/web-docs/reference/custom-operations/string-comparison-operation.md
@@ -0,0 +1,150 @@
+# Starts-With / Ends-With Operation
+
+OpenFeature allows clients to pass contextual information which can then be used during a flag evaluation. For example, a client could pass the email address of the user.
+
+In some scenarios, it is desirable to use that contextual information to segment the user population further and thus return dynamic values.
+
+The `starts_with`/`ends_with` operation is a custom JsonLogic operation which selects a variant based on
+whether the specified property starts/ends with a certain value.
+The value is an array consisting of exactly two items, which both need to resolve to a string value.
+The first entry of the array represents the property to be considered, while the second entry represents
+the target value, i.e. the prefix that needs to be present in the value of the referenced property.
+This value should typically be something that remains consistent for the duration of a users session (e.g. email or session ID).
+The `starts_with` evaluation returns a boolean, indicating whether the condition has been met.
+
+```js
+// starts_with property name used in a targeting rule
+"starts_with": [
+ // Evaluation context property the be evaluated
+ {"var": "email"},
+ // prefix that has to be present in the value of the referenced property
+ "user@faas"
+]
+```
+
+## Example for 'starts_with' Operation
+
+Flags defined as such:
+
+```json
+{
+ "flags": {
+ "headerColor": {
+ "variants": {
+ "red": "#FF0000",
+ "blue": "#0000FF",
+ "green": "#00FF00"
+ },
+ "defaultVariant": "blue",
+ "state": "ENABLED",
+ "targeting": {
+ "if": [
+ {
+ "starts_with": [{"var": "email"}, "user@faas"]
+ },
+ "red", "green"
+ ]
+ }
+ }
+ }
+}
+```
+
+will return variant `red`, if the value of the `email` property starts with `user@faas`, and the variant `green` otherwise.
+
+Command:
+
+```shell
+curl -X POST "localhost:8013/schema.v1.Service/ResolveString" -d '{"flagKey":"headerColor","context":{"email": "user@faas.com"}}' -H "Content-Type: application/json"
+```
+
+Result:
+
+```json
+{"value":"#00FF00","reason":"TARGETING_MATCH","variant":"red"}
+```
+
+Command:
+
+```shell
+curl -X POST "localhost:8013/schema.v1.Service/ResolveString" -d '{"flagKey":"headerColor","context":{"email": "foo@bar.com"}}' -H "Content-Type: application/json"
+```
+
+Result:
+
+```shell
+{"value":"#0000FF","reason":"TARGETING_MATCH","variant":"green"}
+```
+
+## EndsWith Operation Configuration
+
+The `ends_with` evaluation can be added as part of a targeting definition.
+The value is an array consisting of exactly two items, which both need to resolve to a string value.
+The first entry of the array represents the property to be considered, while the second entry represents
+the target value, i.e. the suffix that needs to be present in the value of the referenced property.
+This value should typically be something that remains consistent for the duration of a users session (e.g. email or session ID).
+The `ends_with` evaluation returns a boolean, indicating whether the condition has been met.
+
+```js
+// starts_with property name used in a targeting rule
+"ends_with": [
+ // Evaluation context property the be evaluated
+ {"var": "email"},
+ // suffix that has to be present in the value of the referenced property
+ "faas.com"
+]
+```
+
+## Example for 'ends_with' Operation
+
+Flags defined as such:
+
+```json
+{
+ "flags": {
+ "headerColor": {
+ "variants": {
+ "red": "#FF0000",
+ "blue": "#0000FF",
+ "green": "#00FF00"
+ },
+ "defaultVariant": "blue",
+ "state": "ENABLED",
+ "targeting": {
+ "if": [
+ {
+ "ends_with": [{"var": "email"}, "faas.com"]
+ },
+ "red", "green"
+ ]
+ }
+ }
+ }
+}
+```
+
+will return variant `red`, if the value of the `email` property ends with `faas.com`, and the variant `green` otherwise.
+
+Command:
+
+```shell
+curl -X POST "localhost:8013/schema.v1.Service/ResolveString" -d '{"flagKey":"headerColor","context":{"email": "user@faas.com"}}' -H "Content-Type: application/json"
+```
+
+Result:
+
+```json
+{"value":"#00FF00","reason":"TARGETING_MATCH","variant":"red"}
+```
+
+Command:
+
+```shell
+curl -X POST "localhost:8013/schema.v1.Service/ResolveString" -d '{"flagKey":"headerColor","context":{"email": "foo@bar.com"}}' -H "Content-Type: application/json"
+```
+
+Result:
+
+```shell
+{"value":"#0000FF","reason":"TARGETING_MATCH","variant":"green"}
+```
diff --git a/web-docs/reference/flag-definitions.md b/web-docs/reference/flag-definitions.md
new file mode 100644
index 000000000..550c311fc
--- /dev/null
+++ b/web-docs/reference/flag-definitions.md
@@ -0,0 +1,293 @@
+# Flag Definitions
+
+## Flags
+
+`flags` is a **required** property.
+The flags property is a top level property that contains a collection of individual flags and their corresponding flag configurations.
+
+```json
+{
+ "flags": {
+ ...
+ }
+}
+```
+
+## Flag Definition
+
+`flag key` is a **required** property.
+The flag key **must** uniquely identify a flag so that it can be used during flag evaluation.
+The flag key **should** convey the intent of the flag.
+
+```json
+{
+ "flags": {
+ "new-welcome-banner": {
+ ...
+ }
+ }
+}
+```
+
+## Flag properties
+
+A fully configured flag may look like this.
+
+```json
+{
+ "flags": {
+ "new-welcome-banner": {
+ "state": "ENABLED",
+ "variants": {
+ "true": true,
+ "false": false
+ },
+ "defaultVariant": "false",
+ "targeting": { "in": ["@example.com", { "var": "email" }] }
+ }
+ }
+}
+```
+
+See below for a detailed description of each property.
+
+### State
+
+`state` is a **required** property.
+Validate states are "ENABLED" or "DISABLED".
+When the state is set to "DISABLED", flagd will behave like the flag doesn't exist.
+
+Example:
+
+```json
+"state": "ENABLED"
+```
+
+### Variants
+
+`variants` is a **required** property.
+It is an object containing the possible variations supported by the flag.
+All the values of the object **must** be the same type (e.g. boolean, numbers, string, JSON).
+The type used as the variant value will correspond directly affects how the flag is accessed.
+For example, to use a flag configured with boolean values the `/schema.v1.Service/ResolveBoolean` path should be used.
+If another path such as `/schema.v1.Service/ResolveString` is called, a type mismatch occurred and an error is returned.
+
+Example:
+
+```json
+"variants": {
+ "red": "c05543",
+ "green": "2f5230",
+ "blue": "0d507b"
+}
+```
+
+Example:
+
+```json
+"variants": {
+ "on": true,
+ "off": false
+}
+```
+
+Example of an invalid configuration:
+
+```json
+"variants": {
+ "on": true,
+ "off": "false"
+}
+```
+
+### Default Variant
+
+`defaultVariant` is a **required** property.
+The value **must** match the name of one of the variants defined above.
+The default variant is always used unless a targeting rule explicitly overrides it.
+
+Example:
+
+```json
+"variants": {
+ "on": true,
+ "off": false
+},
+"defaultVariant": "off"
+```
+
+Example:
+
+```json
+"variants": {
+ "red": "c05543",
+ "green": "2f5230",
+ "blue": "0d507b"
+},
+"defaultVariant": "red"
+```
+
+Example of an invalid configuration:
+
+```json
+"variants": {
+ "red": "c05543",
+ "green": "2f5230",
+ "blue": "0d507b"
+},
+"defaultVariant": "purple"
+```
+
+### Targeting Rules
+
+`targeting` is an **optional** property.
+A targeting rule **must** be valid JSON.
+Flagd uses a modified version of [JSON Logic](https://jsonlogic.com/), as well as some custom pre-processing, to evaluate these rules.
+The output of the targeting rule **must** match the name of one of the variants defined above.
+If an invalid or null value is returned by the targeting rule, the `defaultVariant` value is used.
+If no targeting rules are defined, the response reason will always be `STATIC`, this allows for the flag values to be cached, this behavior is described [here](../other_resources/caching.md).
+
+#### Evaluation Context
+
+Evaluation context is included as part of the evaluation request.
+For example, when accessing flagd via HTTP, the POST body may look like this:
+
+```json
+{
+ "flagKey": "booleanFlagKey",
+ "context": {
+ "email": "noreply@example.com"
+ }
+}
+```
+
+The evaluation context can be accessed in targeting rules using the `var` operation followed the evaluation context property name.
+
+| Description | Example |
+| -------------------------------------------------------------- | --------------------------------------------- |
+| Retrieve property from the evaluation context | `#!json { "var": "email" }` |
+| Retrieve property from the evaluation context or use a default | `#!json { "var": ["email", "noreply@example.com"] }` |
+| Retrieve a nested property from the evaluation context | `#!json { "var": "user.email" }` |
+
+> For more information, see the `var` section in the [JSON Logic documentation](https://jsonlogic.com/operations.html#var).
+
+#### Conditions
+
+Conditions can be used to control the logical flow and grouping of targeting rules.
+
+| Conditional | Example |
+| ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
+| If | Logic: `#!json {"if" : [ true, "yes", "no" ]}` Result: `"yes"`
Logic: `#!json {"and" : [ true, true ]}` Result: `true` |
+
+#### Operations
+
+Operations are used to take action on, or compare properties retrieved from the context.
+These are provided out-of-the-box by JsonLogic.
+
+| Operator | Description | Context type | Example |
+| ---------------------- | -------------------------------------------------------------------- | ------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| Equals | Attribute equals the specified value, with type coercion. | any | Logic: `#!json { "==" : [1, 1] }` Result: `true`
Logic: `#!json { "===" : [1, "1"] }` Result: `false` |
+| Not equals | Attribute doesn't equal the specified value, with type coercion. | any | Logic: `#!json { "!=" : [1, 2] }` Result: `true`
Logic: `#!json { "!=" : [1, "1"] }` Result: `false` |
+| Strict not equal | Attribute doesn't equal the specified value, with strict comparison. | any | Logic: `#!json { "!==" : [1, 2] }` Result: `true`
Logic: `#!json { "!==" : [1, "1"] }` Result: `true` |
+| Exists | Attribute is defined | any | Logic: `#!json { "!!": [ "mike" ] }` Result: `true`
Logic: `#!json { "!!": [ "" ] }` Result: `false` |
+| Not exists | Attribute is not defined | any | Logic: `#!json {"!": [ "mike" ] }` Result: `false`
Logic: `#!json {"!": [ "" ] }` Result: `true` |
+| Greater than | Attribute is greater than the specified value | number | Logic: `#!json { ">" : [2, 1] }` Result: `true`
Logic: `#!json { ">" : [1, 2] }` Result: `false` |
+| Greater than or equals | Attribute is greater or equal to the specified value | number | Logic: `#!json { ">=" : [2, 1] }` Result: `true`
Logic: `#!json { ">=" : [1, 1] }` Result: `true` |
+| Less than | Attribute is less than the specified value | number | Logic: `#!json { "<" : [1, 2] }` Result: `true`
Logic: `#!json { "<" : [2, 1] }` Result: `false` |
+| Less than or equals | Attribute is less or equal to the specified value | number | Logic: `#!json { "<=" : [1, 1] }` Result: `true`
Logic: `#!json { "<=" : [2, 1] }` Result: `false` |
+| Between | Attribute between the specified values | number | Logic: `#!json { "<" : [1, 5, 10]}` Result: `true`
Logic: `#!json { "<" : [1, 11, 10] }` Result: `false` |
+| Between inclusive | Attribute between or equal to the specified values | number | Logic: `#!json {"<=" : [1, 1, 10] }` Result: `true`
Logic: `#!json { "in":["Illinois", "Springfield"] }` Result: `false` |
+| Not contains | Does not contain a string | string | Logic: `#!json { "!": { "in":["Spring", "Springfield"] } }` Result: `false`
Logic: `#!json { "!": { "in":["Illinois", "Springfield"] } }` Result: `true` |
+| In | Attribute is in an array of strings | string | Logic: `#!json { "in" : [ "Mike", ["Bob", "Mike"]] }` Result: `true`
Logic: `#!json { "in":["Todd", ["Bob", "Mike"]] }` Result: `false` |
+| Not it | Attribute is not in an array of strings | string | Logic: `#!json { "!": { "in" : [ "Mike", ["Bob", "Mike"]] } }` Result: `false`
Logic: `#!json { "!": { "in":["Todd", ["Bob", "Mike"]] } }` Result: `true` |
+
+#### Custom Operations
+
+These are custom operations specific to flagd and flagd providers.
+They are purpose built extensions to JsonLogic in order to support common feature flag use cases.
+
+| Function | Description | Example |
+| ------------- | --------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| `fractional` | Deterministic, pseudorandom fractional distribution | Logic: `#!json { "fractional" : [ { "var": "email" }, [ "red" , 50], [ "green" , 50 ] ] }` Result: Pseudo randomly `red` or `green` based on the evaluation context property `email`.
Additional documentation can be found [here](./custom-operations/fractional.md) |
+| `starts_with` | Attribute starts with the specified value | Logic: `#!json { "starts_with" : [ "192.168.0.1", "192.168"] }` Result: `true`
Logic: `#!json { "starts_with" : [ "10.0.0.1", "192.168"] }` Result: `false` Additional documentation can be found [here](./custom-operations/string-comparision.md) |
+| `ends_with` | Attribute ends with the specified value | Logic: `#!json { "ends_with" : [ "noreply@example.com", "@example.com"] }` Result: `true`
Logic: `#!json { ends_with" : [ "noreply@example.com", "@test.com"] }` Result: `false` Additional documentation can be found [here](./custom-operations/string-comparision.md) |
+| `sem_ver` | Attribute matches a semantic versioning condition | Logic: `#!json {"sem_ver": ["1.1.2", ">=", "1.0.0"]}` Result: `true`
Additional documentation can be found [here](./custom-operations/semver-comparison.md) |
+
+## Shared evaluators
+
+`$evaluators` is an **optional** property.
+It's a collection of shared targeting configurations used to reduce the number of duplicated targeting rules.
+
+Example:
+
+```json
+{
+ "flags": {
+ "fibAlgo": {
+ "variants": {
+ "recursive": "recursive",
+ "memo": "memo",
+ "loop": "loop",
+ "binet": "binet"
+ },
+ "defaultVariant": "recursive",
+ "state": "ENABLED",
+ "targeting": {
+ "if": [
+ {
+ "$ref": "emailWithFaas"
+ },
+ "binet",
+ null
+ ]
+ }
+ },
+ "headerColor": {
+ "variants": {
+ "red": "#FF0000",
+ "blue": "#0000FF",
+ "green": "#00FF00",
+ "yellow": "#FFFF00"
+ },
+ "defaultVariant": "red",
+ "state": "ENABLED",
+ "targeting": {
+ "if": [
+ {
+ "$ref": "emailWithFaas"
+ },
+ {
+ "fractional": [
+ { "var": "email" },
+ ["red", 25],
+ ["blue", 25],
+ ["green", 25],
+ ["yellow", 25]
+ ]
+ },
+ null
+ ]
+ }
+ }
+ },
+ "$evaluators": {
+ "emailWithFaas": {
+ "in": [
+ "@faas.com",
+ {
+ "var": ["email"]
+ }
+ ]
+ }
+ }
+}
+```
+
+## Examples
+
+Sample configurations can be found at .
diff --git a/web-docs/reference/flagd-cli/flagd.md b/web-docs/reference/flagd-cli/flagd.md
new file mode 100644
index 000000000..97c4ae6a6
--- /dev/null
+++ b/web-docs/reference/flagd-cli/flagd.md
@@ -0,0 +1,18 @@
+
+## flagd
+
+Flagd is a simple command line tool for fetching and presenting feature flags to services. It is designed to conform to Open Feature schema for flag definitions.
+
+### Options
+
+```
+ --config string config file (default is $HOME/.agent.yaml)
+ -x, --debug verbose logging
+ -h, --help help for flagd
+```
+
+### SEE ALSO
+
+* [flagd start](flagd_start) - Start flagd
+* [flagd version](flagd_version) - Print the version number of FlagD
+
diff --git a/web-docs/reference/flagd-cli/flagd/flagd.md b/web-docs/reference/flagd-cli/flagd/flagd.md
new file mode 100644
index 000000000..97c4ae6a6
--- /dev/null
+++ b/web-docs/reference/flagd-cli/flagd/flagd.md
@@ -0,0 +1,18 @@
+
+## flagd
+
+Flagd is a simple command line tool for fetching and presenting feature flags to services. It is designed to conform to Open Feature schema for flag definitions.
+
+### Options
+
+```
+ --config string config file (default is $HOME/.agent.yaml)
+ -x, --debug verbose logging
+ -h, --help help for flagd
+```
+
+### SEE ALSO
+
+* [flagd start](flagd_start) - Start flagd
+* [flagd version](flagd_version) - Print the version number of FlagD
+
diff --git a/web-docs/reference/flagd-cli/flagd/flagd_start.md b/web-docs/reference/flagd-cli/flagd/flagd_start.md
new file mode 100644
index 000000000..a633b66ad
--- /dev/null
+++ b/web-docs/reference/flagd-cli/flagd/flagd_start.md
@@ -0,0 +1,41 @@
+
+## flagd start
+
+Start flagd
+
+```
+flagd start [flags]
+```
+
+### Options
+
+```
+ -b, --bearer-token string DEPRECATED: Superseded by --sources.
+ -C, --cors-origin strings CORS allowed origins, * will allow all origins
+ -e, --evaluator string DEPRECATED: Set an evaluator e.g. json, yaml/yml.Please note that yaml/yml and json evaluations work the same (yaml/yml files are converted to json internally) (default "json")
+ -h, --help help for start
+ -z, --log-format string Set the logging format, e.g. console or json (default "console")
+ -t, --metrics-exporter string Set the metrics exporter. Default(if unset) is Prometheus. Can be override to otel - OpenTelemetry metric exporter. Overriding to otel require otelCollectorURI to be present
+ -m, --metrics-port int32 Port to serve metrics on (default 8014)
+ -o, --otel-collector-uri string Set the grpc URI of the OpenTelemetry collector for flagd runtime. If unset, the collector setup will be ignored and traces will not be exported.
+ -p, --port int32 Port to listen on (default 8013)
+ -c, --server-cert-path string Server side tls certificate path
+ -k, --server-key-path string Server side tls key path
+ -d, --socket-path string Flagd socket path. With grpc the service will become available on this address. With http(s) the grpc-gateway proxy will use this address internally.
+ -s, --sources string JSON representation of an array of SourceConfig objects. This object contains 2 required fields, uri (string) and provider (string). Documentation for this object: https://github.com/open-feature/flagd/blob/main/docs/configuration/configuration.md#sync-provider-customisation
+ -y, --sync-provider string DEPRECATED: Set a sync provider e.g. filepath or remote
+ -a, --sync-provider-args stringToString DEPRECATED: Sync provider arguments as key values separated by = (default [])
+ -f, --uri .yaml/.yml/.json Set a sync provider uri to read data from, this can be a filepath,url (http and grpc) or FeatureFlagConfiguration. When flag keys are duplicated across multiple providers the merge priority follows the index of the flag arguments, as such flags from the uri at index 0 take the lowest precedence, with duplicated keys being overwritten by those from the uri at index 1. Please note that if you are using filepath, flagd only supports files with .yaml/.yml/.json extension.
+```
+
+### Options inherited from parent commands
+
+```
+ --config string config file (default is $HOME/.agent.yaml)
+ -x, --debug verbose logging
+```
+
+### SEE ALSO
+
+* [flagd](flagd) - Flagd is a simple command line tool for fetching and presenting feature flags to services. It is designed to conform to Open Feature schema for flag definitions.
+
diff --git a/web-docs/reference/flagd-cli/flagd/flagd_version.md b/web-docs/reference/flagd-cli/flagd/flagd_version.md
new file mode 100644
index 000000000..305ecafb2
--- /dev/null
+++ b/web-docs/reference/flagd-cli/flagd/flagd_version.md
@@ -0,0 +1,26 @@
+
+## flagd version
+
+Print the version number of FlagD
+
+```
+flagd version [flags]
+```
+
+### Options
+
+```
+ -h, --help help for version
+```
+
+### Options inherited from parent commands
+
+```
+ --config string config file (default is $HOME/.agent.yaml)
+ -x, --debug verbose logging
+```
+
+### SEE ALSO
+
+* [flagd](flagd) - Flagd is a simple command line tool for fetching and presenting feature flags to services. It is designed to conform to Open Feature schema for flag definitions.
+
diff --git a/web-docs/reference/flagd-cli/flagd_start.md b/web-docs/reference/flagd-cli/flagd_start.md
new file mode 100644
index 000000000..a633b66ad
--- /dev/null
+++ b/web-docs/reference/flagd-cli/flagd_start.md
@@ -0,0 +1,41 @@
+
+## flagd start
+
+Start flagd
+
+```
+flagd start [flags]
+```
+
+### Options
+
+```
+ -b, --bearer-token string DEPRECATED: Superseded by --sources.
+ -C, --cors-origin strings CORS allowed origins, * will allow all origins
+ -e, --evaluator string DEPRECATED: Set an evaluator e.g. json, yaml/yml.Please note that yaml/yml and json evaluations work the same (yaml/yml files are converted to json internally) (default "json")
+ -h, --help help for start
+ -z, --log-format string Set the logging format, e.g. console or json (default "console")
+ -t, --metrics-exporter string Set the metrics exporter. Default(if unset) is Prometheus. Can be override to otel - OpenTelemetry metric exporter. Overriding to otel require otelCollectorURI to be present
+ -m, --metrics-port int32 Port to serve metrics on (default 8014)
+ -o, --otel-collector-uri string Set the grpc URI of the OpenTelemetry collector for flagd runtime. If unset, the collector setup will be ignored and traces will not be exported.
+ -p, --port int32 Port to listen on (default 8013)
+ -c, --server-cert-path string Server side tls certificate path
+ -k, --server-key-path string Server side tls key path
+ -d, --socket-path string Flagd socket path. With grpc the service will become available on this address. With http(s) the grpc-gateway proxy will use this address internally.
+ -s, --sources string JSON representation of an array of SourceConfig objects. This object contains 2 required fields, uri (string) and provider (string). Documentation for this object: https://github.com/open-feature/flagd/blob/main/docs/configuration/configuration.md#sync-provider-customisation
+ -y, --sync-provider string DEPRECATED: Set a sync provider e.g. filepath or remote
+ -a, --sync-provider-args stringToString DEPRECATED: Sync provider arguments as key values separated by = (default [])
+ -f, --uri .yaml/.yml/.json Set a sync provider uri to read data from, this can be a filepath,url (http and grpc) or FeatureFlagConfiguration. When flag keys are duplicated across multiple providers the merge priority follows the index of the flag arguments, as such flags from the uri at index 0 take the lowest precedence, with duplicated keys being overwritten by those from the uri at index 1. Please note that if you are using filepath, flagd only supports files with .yaml/.yml/.json extension.
+```
+
+### Options inherited from parent commands
+
+```
+ --config string config file (default is $HOME/.agent.yaml)
+ -x, --debug verbose logging
+```
+
+### SEE ALSO
+
+* [flagd](flagd) - Flagd is a simple command line tool for fetching and presenting feature flags to services. It is designed to conform to Open Feature schema for flag definitions.
+
diff --git a/web-docs/reference/flagd-cli/flagd_version.md b/web-docs/reference/flagd-cli/flagd_version.md
new file mode 100644
index 000000000..305ecafb2
--- /dev/null
+++ b/web-docs/reference/flagd-cli/flagd_version.md
@@ -0,0 +1,26 @@
+
+## flagd version
+
+Print the version number of FlagD
+
+```
+flagd version [flags]
+```
+
+### Options
+
+```
+ -h, --help help for version
+```
+
+### Options inherited from parent commands
+
+```
+ --config string config file (default is $HOME/.agent.yaml)
+ -x, --debug verbose logging
+```
+
+### SEE ALSO
+
+* [flagd](flagd) - Flagd is a simple command line tool for fetching and presenting feature flags to services. It is designed to conform to Open Feature schema for flag definitions.
+
diff --git a/web-docs/reference/monitoring.md b/web-docs/reference/monitoring.md
new file mode 100644
index 000000000..71304bd41
--- /dev/null
+++ b/web-docs/reference/monitoring.md
@@ -0,0 +1,156 @@
+# Monitoring
+
+## Readiness & Liveness probes
+
+### HTTP
+
+Flagd exposes HTTP liveness and readiness probes.
+These probes can be used for K8s deployments.
+With default start-up configurations, these probes are exposed on the metrics port (default: 8014) at the following URLs,
+
+- Liveness:
+- Readiness:
+
+### gRPC
+
+Flagd exposes a [standard gRPC liveness check](https://github.com/grpc/grpc/blob/master/doc/health-checking.md) on the metrics port (default: 8014).
+
+### Definition of Liveness
+
+The liveness probe becomes active and HTTP 200 status is served as soon as Flagd service is up and running.
+
+### Definition of Readiness
+
+The readiness probe becomes active similar to the liveness probe as soon as Flagd service is up and running.
+However,
+the probe emits HTTP 412 until all sync providers are ready.
+This status changes to HTTP 200 when all sync providers at
+least have one successful data sync.
+The status does not change from there on.
+
+## OpenTelemetry
+
+flagd provides telemetry data out of the box. This telemetry data is compatible with OpenTelemetry.
+
+By default, the Prometheus exporter is used for metrics which can be accessed via the `/metrics` endpoint. For example,
+with default startup flags, metrics are exposed at `http://localhost:8014/metrics`.
+
+Given below is the current implementation overview of flagd telemetry internals,
+
+![flagd telemetry](../images/flagd-telemetry.png)
+
+## Metrics
+
+flagd expose following metrics,
+
+- `http.server.duration`
+- `http.server.response.size`
+- `http.server.active_requests`
+- `feature_flag.flagd.impression`
+- `feature_flag.flagd.evaluation.reason`
+
+## Traces
+
+flagd expose following traces,
+
+- `flagEvaluationService(resolveX)` - SpanKind server
+ - `jsonEvaluator(resolveX)` - SpanKind internal
+- `jsonEvaluator(setState)` - SpanKind internal
+
+## Export to OTEL collector
+
+flagd can be configured to connect to [OTEL collector](https://opentelemetry.io/docs/collector/). This requires startup
+flag `metrics-exporter` to be `otel` and a valid `otel-collector-uri`. For example,
+
+`flagd start --uri file:/flags.json --metrics-exporter otel --otel-collector-uri localhost:4317`
+
+### Configure local collector setup
+
+To configure a local collector setup along with Jaeger and Prometheus, you can use following sample docker-compose
+file and configuration files.
+
+Note - content is adopted from
+official [OTEL collector example](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/examples/demo)
+
+#### docker-compose.yaml
+
+```yaml
+version: "3"
+services:
+ # Jaeger
+ jaeger-all-in-one:
+ image: jaegertracing/all-in-one:latest
+ restart: always
+ ports:
+ - "16686:16686"
+ - "14268"
+ - "14250"
+ # Collector
+ otel-collector:
+ image: otel/opentelemetry-collector:latest
+ restart: always
+ command: [ "--config=/etc/otel-collector-config.yaml" ]
+ volumes:
+ - ./otel-collector-config.yaml:/etc/otel-collector-config.yaml
+ ports:
+ - "1888:1888" # pprof extension
+ - "8888:8888" # Prometheus metrics exposed by the collector
+ - "8889:8889" # Prometheus exporter metrics
+ - "13133:13133" # health_check extension
+ - "4317:4317" # OTLP gRPC receiver
+ - "55679:55679" # zpages extension
+ depends_on:
+ - jaeger-all-in-one
+ prometheus:
+ container_name: prometheus
+ image: prom/prometheus:latest
+ restart: always
+ volumes:
+ - ./prometheus.yaml:/etc/prometheus/prometheus.yml
+ ports:
+ - "9090:9090"
+```
+
+#### otel-collector-config.yaml
+
+```yaml
+receivers:
+ otlp:
+ protocols:
+ grpc:
+exporters:
+ prometheus:
+ endpoint: "0.0.0.0:8889"
+ const_labels:
+ label1: value1
+ jaeger:
+ endpoint: jaeger-all-in-one:14250
+ tls:
+ insecure: true
+processors:
+ batch:
+service:
+ pipelines:
+ traces:
+ receivers: [ otlp ]
+ processors: [ batch ]
+ exporters: [ jaeger ]
+ metrics:
+ receivers: [ otlp ]
+ processors: [ batch ]
+ exporters: [ prometheus ]
+```
+
+#### prometheus.yml
+
+```yaml
+scrape_configs:
+ - job_name: 'otel-collector'
+ scrape_interval: 10s
+ static_configs:
+ - targets: [ 'otel-collector:8889' ]
+ - targets: [ 'otel-collector:8888' ]
+```
+
+Once, configuration files are ready, use `docker-compose up` to start the local setup. With successful startup, you can
+access metrics through [Prometheus](http://localhost:9090/graph) & traces through [Jaeger](http://localhost:16686/).
diff --git a/web-docs/reference/naming.md b/web-docs/reference/naming.md
new file mode 100644
index 000000000..9a42a8147
--- /dev/null
+++ b/web-docs/reference/naming.md
@@ -0,0 +1,6 @@
+# Naming
+
+_flagd_ was conceived as a simple program with a POSIX-style CLI that's designed to run as a service or [daemon](https://en.wikipedia.org/wiki/Daemon_(computing)).
+For this reason, its name is stylized as all lower case: "flagd", consistent with other famous Unix/Linux daemons (_crond_, _sshd_, _systemd_, _ntpd_, _httpd_, etc).
+Although the flagd system has expanded beyond the flagd application itself to include libraries which embed flagd's evaluation engine, the "flagd" stylization should be observed for all components relating to flagd.
+Where possible, please treat "flagd" as a single word, including in library names, packages, variable names, etc.
diff --git a/web-docs/reference/providers.md b/web-docs/reference/providers.md
new file mode 100644
index 000000000..8ff41d4b5
--- /dev/null
+++ b/web-docs/reference/providers.md
@@ -0,0 +1,9 @@
+# Providers
+
+flagd was built from the ground up to be [Openfeature-compliant](../concepts/feature-flagging.md#openfeature-compliance).
+To use it in your application, you must use the [OpenFeature SDK](https://openfeature.dev/docs/reference/technologies/) for your language, along with the associated OpenFeature _provider_.
+For more information about Openfeature providers, see the [OpenFeature documentation](https://openfeature.dev/docs/reference/concepts/provider).
+
+Providers for flagd come in two flavors: those that are built to communicate with a flagd instance (over HTTP or gRPC) and those that embed flagd's evaluation engine directly (note that some providers are capable of operating in either mode). For more information on how to deploy and use flagd, see [architecture](../architecture.md) and [deployment](../deployment.md).
+
+For a catalog of available flagd providers, check out the [OpenFeature ecosystem](https://openfeature.dev/ecosystem?instant_search%5Bquery%5D=flagd&instant_search%5BrefinementList%5D%5Btype%5D%5B0%5D=Provider) page.
diff --git a/web-docs/reference/specifications/custom-operations/fractional-operation-spec.md b/web-docs/reference/specifications/custom-operations/fractional-operation-spec.md
new file mode 100644
index 000000000..69336fab7
--- /dev/null
+++ b/web-docs/reference/specifications/custom-operations/fractional-operation-spec.md
@@ -0,0 +1,191 @@
+# Fractional Operation Specification
+
+This evaluator allows to split the returned variants of a feature flag into different buckets,
+where each bucket can be assigned a percentage, representing how many requests will resolve to the corresponding
+variant.
+
+The sum of all weights must be 100, and the distribution must be performed by using the value of a referenced
+from the evaluation context to hash that value and map it to a value between [0, 100]. It is important to note
+that evaluations MUST be sticky, meaning that flag resolution requests containing the same value for the
+referenced property in their context MUST always resolve to the same variant. For calculating the hash value of the
+referenced evaluation context property, the [MurmurHash3](https://github.com/aappleby/smhasher/blob/master/src/MurmurHash3.cpp)
+hash function should be used. This is to ensure that flag resolution requests yield the same result,
+regardless of which implementation of the in-process flagd provider is being used.
+
+The supplied array must contain at least two items, with the first item being an optional [json logic variable declaration](https://jsonlogic.com/operations.html#var)
+specifying the bucketing property to base the distribution of values on. If not supplied, a concatination of the
+`flagKey` and `targetingKey` are used: `{"cat": [{"var":"$flagd.flagKey"}, {"var":"targetingKey"}]}`.
+The remaining items are `arrays`, each with two values, with the first being `string` item representing the name of the variant, and the
+second being a `float` item representing the percentage for that variant. The percentages of all items must add up to
+100.0, otherwise unexpected behavior can occur during the evaluation. The `data` object can be an arbitrary
+JSON object. Below is an example for a targetingRule containing a `fractional`:
+
+```json
+{
+ "flags": {
+ "headerColor": {
+ "variants": {
+ "red": "#FF0000",
+ "blue": "#0000FF",
+ "green": "#00FF00"
+ },
+ "defaultVariant": "red",
+ "state": "ENABLED",
+ "targeting": {
+ "fractional": [
+ {"var":"email"},
+ [
+ "red",
+ 50
+ ],
+ [
+ "blue",
+ 20
+ ],
+ [
+ "green",
+ 30
+ ]
+ ]
+ }
+ }
+ }
+}
+```
+
+Please note that the implementation of this evaluator can assume that instead of `{"var": "email"}`, it will receive
+the resolved value of that referenced property, as resolving the value will be taken care of by JsonLogic before
+applying the evaluator.
+
+The following flow chart depicts the logic of this evaluator:
+
+```mermaid
+flowchart TD
+A[Parse targetingRule] --> B{Is an array containing at least one item?};
+B -- Yes --> C{Is targetingRule at index 0 a string?};
+B -- No --> D[return nil]
+C -- No --> E[bucketingPropertyValue := default to targetingKey];
+C -- Yes --> F[bucketingPropertyValue := targetingRule at index 0];
+E --> G[Iterate through the remaining elements of the targetingRule array and parse the variants and their percentages];
+F --> G;
+G --> H{Parsing successful?};
+H -- No --> D;
+H -- Yes --> I{Does percentage of variants add up to 100?};
+I -- No --> D;
+I -- Yes --> J[hash := murmur3Hash of bucketingPropertyValue divided by Int64.MaxValue]
+J --> K[Iterate through the variant and increment the threshold by the percentage of each variant. Return the first variant where the bucket is smaller than the threshold.]
+```
+
+As a reference, below is a simplified version of the actual implementation of this evaluator in Go.
+
+```go
+
+type fractionalEvaluationDistribution struct {
+ variant string
+ percentage int
+}
+
+/*
+ values: contains the targeting rule object; e.g.:
+ [
+ {"var":"email"},
+ [
+ "red",
+ 50
+ ],
+ [
+ "blue",
+ 20
+ ],
+ [
+ "green",
+ 30
+ ]
+ ]
+
+ data: contains the evaluation context; e.g.:
+ {
+ "email": "test@faas.com"
+ }
+*/
+func FractionalEvaluation(values, data interface{}) interface{} {
+ // 1. Check if the values object contains at least two elements:
+ valuesArray, ok := values.([]interface{})
+ if !ok {
+ log.Error("fractional evaluation data is not an array")
+ return nil
+ }
+ if len(valuesArray) < 2 {
+ log.Error("fractional evaluation data has length under 2")
+ return nil
+ }
+
+ // 2. Get the target property value used for bucketing the values
+ valueToDistribute, ok := valuesArray[0].(string)
+ if !ok {
+ log.Error("first element of fractional evaluation data isn't of type string")
+ return nil
+ }
+
+ // 3. Parse the fractional values distribution
+ sumOfPercentages := 0
+ var feDistributions []fractionalEvaluationDistribution
+
+ // start at index 1, as the first item of the values array is the target property
+ for i := 1; i < len(valuesArray); i++ {
+ distributionArray, ok := values[i].([]interface{})
+ if !ok {
+ log.Error("distribution elements aren't of type []interface{}")
+ return nil
+ }
+
+ if len(distributionArray) != 2 {
+ log.Error("distribution element isn't length 2")
+ return nil
+ }
+
+ variant, ok := distributionArray[0].(string)
+ if !ok {
+ log.Error("first element of distribution element isn't a string")
+ return nil
+ }
+
+ percentage, ok := distributionArray[1].(float64)
+ if !ok {
+ log.Error("second element of distribution element isn't float")
+ return nil
+ }
+
+ sumOfPercentages += int(percentage)
+
+ feDistributions = append(feDistributions, fractionalEvaluationDistribution{
+ variant: variant,
+ percentage: int(percentage),
+ })
+ }
+
+ // check if the sum of percentages adds up to 100, otherwise log an error
+ if sumOfPercentages != 100 {
+ log.Error("percentages must sum to 100, got: %d", sumOfPercentages)
+ return nil
+ }
+
+ // 4. Calculate the hash of the target property and map it to a number between [0, 99]
+ hashValue := int32(murmur3.StringSum32(value))
+ hashRatio := math.Abs(float64(hashValue)) / math.MaxInt32
+ bucket := int(hashRatio * 100)
+
+ // 5. Iterate through the variant and increment the threshold by the percentage of each variant.
+ // return the first variant where the bucket is smaller than the threshold.
+ rangeEnd := 0
+ for _, dist := range feDistribution {
+ rangeEnd += dist.percentage
+ if bucket < rangeEnd {
+ // return the matching variant
+ return dist.variant
+ }
+ }
+
+ return ""
+}
+```
diff --git a/web-docs/reference/specifications/custom-operations/semver-operation-spec.md b/web-docs/reference/specifications/custom-operations/semver-operation-spec.md
new file mode 100644
index 000000000..56c51f7af
--- /dev/null
+++ b/web-docs/reference/specifications/custom-operations/semver-operation-spec.md
@@ -0,0 +1,45 @@
+# Semantic Versioning Operation Specification
+
+This evaluator checks if the given property within the evaluation context matches a semantic versioning condition.
+It returns 'true', if the value of the given property meets the condition, 'false' if not.
+
+```js
+{
+ "if": [
+ {
+ "sem_ver": [{"var": "version"}, ">=", "1.0.0"]
+ },
+ "red", null
+ ]
+}
+```
+
+The implementation of this evaluator should accept the object containing the `sem_ver` evaluator
+configuration, and a `data` object containing the evaluation context.
+The 'sem_ver' evaluation rule contains exactly three items:
+
+1. Target property value: the resolved value of the target property referenced in the targeting rule
+2. Operator: One of the following: `=`, `!=`, `>`, `<`, `>=`, `<=`, `~` (match minor version), `^` (match major version)
+3. Target value: this needs to resolve to a semantic versioning string. If this condition is not met, the evaluator should
+log an appropriate error message and return `nil`
+
+The `sem_ver` evaluation returns a boolean, indicating whether the condition has been met.
+
+Please note that the implementation of this evaluator can assume that instead of `{"var": "version"}`, it will receive
+the resolved value of that referenced property, as resolving the value will be taken care of by JsonLogic before
+applying the evaluator.
+
+The following flow chart depicts the logic of this evaluator:
+
+```mermaid
+flowchart TD
+A[Parse targetingRule] --> B{Is an array containing exactly three items?};
+B -- Yes --> C{Is targetingRule at index 0 a semantic version string?};
+B -- No --> D[Return nil];
+C -- Yes --> E{Is targetingRule at index 1 a supported operator?};
+C -- No --> D;
+E -- Yes --> F{Is targetingRule at index 2 a semantic version string?};
+E -- No --> D;
+F -- No --> D;
+F --> G[Compare the two versions using the operator and return a boolean value indicating if they match];
+```
diff --git a/web-docs/reference/specifications/custom-operations/string-comparison-operation-spec.md b/web-docs/reference/specifications/custom-operations/string-comparison-operation-spec.md
new file mode 100644
index 000000000..3e9832563
--- /dev/null
+++ b/web-docs/reference/specifications/custom-operations/string-comparison-operation-spec.md
@@ -0,0 +1,40 @@
+# Starts-With / Ends-With Operation Specification
+
+This evaluator selects a variant based on whether the specified property within the evaluation context
+starts/ends with a certain string.
+
+```js
+// starts_with property name used in a targeting rule
+"starts_with": [
+ // Evaluation context property the be evaluated
+ {"var": "email"},
+ // prefix that has to be present in the value of the referenced property
+ "user@faas"
+]
+```
+
+The implementation of this evaluator should accept the object containing the `starts_with` or `ends_with` evaluator
+configuration, and a `data` object containing the evaluation context.
+The `starts_with`/`ends_with` evaluation rule contains exactly two items:
+
+1. The resolved string value from the evaluation context
+2. The target string value
+
+The `starts_with`/`ends_with` evaluation returns a boolean, indicating whether the condition has been met.
+
+Please note that the implementation of this evaluator can assume that instead of `{"var": "email"}`, it will receive
+the resolved value of that referenced property, as resolving the value will be taken care of by JsonLogic before
+applying the evaluator.
+
+The following flow chart depicts the logic of this evaluator:
+
+```mermaid
+flowchart TD
+A[Parse targetingRule] --> B{Is an array containing exactly two items?};
+B -- Yes --> C{Is targetingRule at index 0 a string?};
+B -- No --> D[Return nil];
+C -- Yes --> E{Is targetingRule at index 1 a string?};
+C -- No --> D;
+E -- No --> D;
+E --> F[Return a boolean value indicating if the first string starts/ends with the second string];
+```
diff --git a/web-docs/reference/specifications/in-process-providers.md b/web-docs/reference/specifications/in-process-providers.md
new file mode 100755
index 000000000..020804617
--- /dev/null
+++ b/web-docs/reference/specifications/in-process-providers.md
@@ -0,0 +1,247 @@
+# Creating an in-process flagd provider
+
+By default, **flagd** is a remote service that is accessed via **grpc** by a client application to retrieve feature flags.
+Depending on the environment, flagd therefore is usually deployed as a standalone service, e.g. as a Kubernetes Deployment,
+or injected as a sidecar container into the pod running the client application,
+as it is done in the [OpenFeature Operator](https://github.com/open-feature/open-feature-operator).
+An in-process flagd provider, on the other hand, is designed to be embedded into the application and therefore
+no communication outside the process of the application for feature flag evaluation is needed. This can be desired by some architectures,
+especially if flag retrievals should not take longer than a certain amount of time.
+
+The in-process flagd provider is responsible for creating an abstraction between the [JsonLogic](https://jsonlogic.com) based evaluation of flag configurations following the [flag configuration scheme](https://github.com/open-feature/schemas/blob/main/json/flagd-definitions.json) used by `flagd` and the OpenFeature SDK (for the [chosen technology](https://openfeature.dev/docs/reference/technologies/)).
+
+Prerequisites:
+
+- Understanding of [general provider concepts](https://openfeature.dev/docs/reference/concepts/provider/)
+- Proficiency in the chosen programming language (check the language isn't already covered by the [existing providers](../usage/flagd_providers.md))
+
+The Flag definition containing the feature flags and JsonLogic based targeting rules shall be retrieved by the
+in-process flagd provider via a gRPC client connection to a sync server, such as [flagd-proxy](https://github.com/open-feature/flagd/tree/main/flagd-proxy).
+
+## Sync source
+
+An implementation of an in-process flagd-provider must accept the following environment variables which determine the sync source:
+
+- `FLAGD_SOURCE_URI`: The URI identifying the sync source. Depending on the sync provider type, this can be the URI of a gRPC service providing the `sync` API required by the in-process flagd provider, or the name of a [core.openfeature.dev/v1alpha2.FeatureFlagConfiguration](https://github.com/open-feature/open-feature-operator/blob/main/docs/crds.md#featureflagconfiguration-1) Custom Resource containing the flag definition.
+- `FLAGD_SOURCE_PROVIDER_TYPE`: The type of the provider. E.g. `grpc` or `kubernetes`.
+- `FLAGD_SOURCE_SELECTOR`: Optional selector for the feature flag definition of interest. This is used as a `selector` for the flagd-proxie's sync API to identify a flag definition within a collection of feature flag definition.
+
+An implementation of an in-process flagd provider should provide a source for retrieving the flag definition, namely a gRPC source.
+Other sources may be desired eventually, so separation of concerns should be maintained between the abstractions evaluating flags and those retrieving confirmation.
+
+## gRPC sources
+
+gRPC sync sources are identified by the `provider` field set to `grpc`.
+When such a sync source is specified, the in-process flagd provider should connect to the gRPC service located at the `uri` of the sync source, and use its [sync API](./protos.md#syncv1sync_serviceproto) to retrieve the feature flag definition.
+If the `selector` field of the sync source is set, that selector should be passed through to the `Sync` and `FetchAllFlags` requests sent to the gRPC server.
+
+### Protobuf
+
+Protobuf schemas define the contract between a client (flagd or the in-process provider implementation) and server (`flagd-proxy`).
+`flagd-proxy`'s schemas are defined [here](https://github.com/open-feature/schemas/tree/main/protobuf/sync/v1).
+
+#### Code generation for gRPC sync
+
+Leverage the [buf CLI](https://docs.buf.build/installation) or protoc to generate a `flagd-proxy` client in the chosen technology:
+
+Add the [open-feature schema repository](https://github.com/open-feature/schemas) as a submodule
+
+```shell
+git submodule add --force https://github.com/open-feature/schemas.git
+```
+
+Create a `buf.gen.{chosen language}.yaml` for the chosen language in `schemas/protobuf` (if it doesn't already exist) using one of the other files as a template (find a plugin for the chosen language [here](https://buf.build/protocolbuffers/plugins)) and create a pull request with this file.
+
+Generate the code (this step ought to be automated in the build process for the chosen technology so that the generated code is never committed)
+
+```shell
+cd schemas/protobuf
+buf generate --template buf.gen.{chosen language}.yaml
+```
+
+As an alternative to buf, use the .proto file directly along with whatever protoc-related tools or plugins avaialble for your language.
+
+Move the generated code (following convention for the chosen language) and add its location to .gitignore
+
+Note that for the in-process provider only the `sync` package will be relevant, as it does not communicate with `flagd`, but only with compliant gRPC services such as `flagd-proxy`.
+
+## JsonLogic evaluation
+
+An in-process flagd provider should provide the feature set offered by [JsonLogic](https://jsonlogic.com) to evaluate flag resolution requests for a given context.
+If available, the JsonLogic library for the chosen technology should be used.
+
+### Custom JsonLogic evaluators
+
+In addition to the built-in evaluators provided by JsonLogic, the following custom targeting rules should be implemented by the provider:
+
+- [Fractional operation](../../reference/custom-operations/fractional-operation.md):
+This evaluator allows to split the returned variants of a feature flag into different buckets, where each bucket
+can be assigned a percentage, representing how many requests will resolve to the corresponding variant.
+The sum of all weights must be 100, and the distribution must be performed by using the value of a referenced
+from the evaluation context to hash that value and map it to a value between [0, 100].
+It is important to note that evaluations MUST be sticky, meaning that flag resolution requests containing the
+same value for the referenced property in their context MUST always resolve to the same variant.
+For calculating the hash value of the referenced evaluation context property,
+the [MurmurHash3](https://github.com/aappleby/smhasher/blob/master/src/MurmurHash3.cpp) hash function should be used.
+This is to ensure that flag resolution requests yield the same result, regardless of which implementation of
+the in-process flagd provider is being used. For more specific implementation guidelines, please refer to
+[this document](./custom-operations/fractional-operation-spec.md).
+- [Semantic version evaluation](../../reference/custom-operations/semver-operation.md):
+This evaluator checks if the given property within the evaluation context matches a semantic versioning condition.
+It returns 'true', if the value of the given property meets the condition, 'false' if not.
+For more specific implementation guidelines, please refer to [this document](../specifications/custom-operations/semver-operation-spec.md).
+- [StartsWith/EndsWith evaluation](../../reference/custom-operations/string-comparison-operation.md):
+This evaluator selects a variant based on whether the specified property within the evaluation context
+starts/ends with a certain string.
+For more specific implementation guidelines, please refer to [this document](./custom-operations/string-comparison-operation-spec.md).
+
+## Provider construction
+
+(**using Go as an example**)
+
+Create a provider struct/class/type (whichever is relevant to the chosen language) with an exported (public) constructor allowing configuration (e.g. `flagd` host).
+Give the provider an un-exported (private) client field, set this field as the client generated by the previous step.
+
+Create methods for the provider to satisfy the chosen language SDK's provider interface.
+These methods ought to wrap the built client's methods.
+
+```go
+type Provider struct {
+ evaluator IJsonEvaluator
+}
+
+type ProviderOption func(*Provider)
+
+func NewProvider(options ...ProviderOption) *Provider {
+ provider := &Provider{}
+ for _, opt := range opts {
+ opt(provider)
+ }
+
+ // create a store that is responsible for retrieving the flag configurations
+ // from the sources that are given to the provider via the options
+ s := store.NewFlags()
+ s.FlagSources = append(s.FlagSources, os.Getenv("FLAGD_SOURCE_URI"))
+ s.SourceMetadata[provider.URI] = store.SourceDetails{
+ Source: os.Getenv("FLAGD_SOURCE_URI"),
+ Selector: os.Getenv("FLAGD_SOURCE_SELECTOR")),
+ }
+
+ // derive evaluator
+ provider.evaluator := setupJSONEvaluator(logger, s)
+
+ return provider
+}
+
+func WithHost(host string) ProviderOption {
+ return func(p *Provider) {
+ p.flagdHost = host
+ }
+}
+
+func (p *Provider) BooleanEvaluation(
+ ctx context.Context, flagKey string, defaultValue bool, evalCtx of.FlattenedContext,
+) of.BoolResolutionDetail {
+
+ res, err := p.evaluator.ResolveBoolean(ctx, flagKey, context)
+
+ if err != nil {
+ return of.BoolResolutionDetail{
+ Value: defaultValue,
+ ProviderResolutionDetail: of.ProviderResolutionDetail{
+ ResolutionError: of.NewGeneralResolutionError(err.Error()),
+ Reason: of.Reason(res.Reason),
+ Variant: res.Variant,
+ },
+ }
+ }
+
+ return of.BoolResolutionDetail{
+ Value: defaultValue,
+ ProviderResolutionDetail: of.ProviderResolutionDetail{
+ Reason: of.Reason(res.Reason),
+ Variant: res.Variant,
+ },
+ }
+}
+
+// ...
+```
+
+## Provider lifecycle, initialization and shutdown
+
+With the release of the v0.6.0 spec, OpenFeature now outlines a lifecycle for in-process flagd provider initialization and shutdown.
+
+In-process flagd providers should do the following to make use of OpenFeature v0.6.0 features:
+
+- start in a `NOT_READY` state
+- fetch the flag definition specified in the sync provider sources and set `state` to `READY` or `ERROR` in the `initialization` function
+ - note that the SDK will automatically emit `PROVIDER_READY`/`PROVIDER_ERROR` according to the termination of the `initialization` function
+- throw an exception or terminate abnormally if a connection cannot be established during `initialization`
+- For gRPC based sources (i.e. flagd-proxy), attempt to restore the streaming connection to flagd-proxy (if the connection cannot be established or is broken):
+ - If flag definition have been retrieved previously, go into `STALE` state to indicate that flag resolution responsees are based on potentially outdated Flag definition.
+ - reconnection should be attempted with an exponential back-off, with a max-delay of `maxSyncRetryInterval` (see [configuration](#configuration))
+ - reconnection should be attempted up to `maxSyncRetryDelay` times (see [configuration](#configuration))
+ - `PROVIDER_READY` and `PROVIDER_CONFIGURATION_CHANGED` should be emitted, in that order, after successful reconnection
+- For Kubernetes sync sources, retry to retrieve the FlagConfiguration resource, using an exponential back-off strategy, with a max-delay of `maxSyncRetryInterval` (see [configuration](#configuration))
+- emit `PROVIDER_CONFIGURATION_CHANGED` event and update ruleset when a `configuration_change` message is received on the streaming connection
+- close the streaming connection in the`shutdown` function
+
+```mermaid
+stateDiagram-v2
+ [*] --> NOT_READY
+ NOT_READY --> READY: initialize(), stream connected, flag configurations retrieved
+ NOT_READY --> ERROR: initialize(), unable to connect (retry)
+ READY --> STALE: previously retrieved flag configurations can not be retrieved anymore (emit stale*)
+ STALE --> READY: connection to flag source reestablished, and latest flag configurations retrieved (emit ready*, changed*)
+ STALE --> ERROR: connection reattempt failed after maxSyncRetries reached (emit error*)
+ READY --> READY: configuration_change (emit changed*)
+ ERROR --> READY: reconnect successful (emit ready*, changed*)
+ ERROR --> ERROR: maxSyncRetries reached
+ ERROR --> [*]: shutdown(), stream disconnected
+```
+
+\* ready=`PROVIDER_READY`, changed=`PROVIDER_CONFIGURATION_CHANGED`, stale=`PROVIDER_STALE`, error=`PROVIDER_ERROR`
+
+## Configuration
+
+Expose means to configure the provider aligned with the following priority system (highest to lowest).
+
+```mermaid
+flowchart LR
+ constructor-parameters -->|highest priority| environment-variables -->|lowest priority| defaults
+```
+
+### Explicit declaration
+
+This takes the form of parameters to the provider's constructor, it has the highest priority.
+
+### Environment variables
+
+Read environment variables with sensible defaults (before applying the values explicitly declared to the constructor).
+
+| Option name | Environment variable name | Type | Options | Default |
+| --------------------------- | ------------------------------------- | ------- | ------------ | -------------------------------------- |
+| host | FLAGD_PROXY_HOST | string | | localhost |
+| port | FLAGD_PROXY_PORT | number | | 8013 |
+| tls | FLAGD_PROXY_TLS | boolean | | false |
+| socketPath | FLAGD_PROXY_SOCKET_PATH | string | | |
+| certPath | FLAGD_PROXY_SERVER_CERT_PATH | string | | |
+| sourceURI | FLAGD_SOURCE_URI | string | | |
+| sourceProviderType | FLAGD_SOURCE_PROVIDER_TYPE | string | | grpc |
+| sourceSelector | FLAGD_SOURCE_SELECTOR | string | | |
+| maxSyncRetries | FLAGD_MAX_SYNC_RETRIES | int | | 0 (0 means unlimited) |
+| maxSyncRetryInterval | FLAGD_MAX_SYNC_RETRY_INTERVAL | int | | 60s |
+
+## Error handling
+
+Handle flag evaluation errors by using the error constructors exported by the SDK (e.g. `openfeature.NewProviderNotReadyResolutionError(ConnectionError)`), thereby allowing the SDK to parse and handle the error appropriately.
+
+## Post creation
+
+The following steps will extend the reach of the newly created provider to other developers of the chosen technology.
+
+### Open an issue to document the provider
+
+Create an issue in openfeature.dev [here](https://github.com/open-feature/openfeature.dev/issues/new?assignees=&labels=provider&template=document-provider.yaml&title=%5BProvider%5D%3A+).
+This will ensure the provider is added to OpenFeature's website.
diff --git a/web-docs/reference/specifications/protos.md b/web-docs/reference/specifications/protos.md
new file mode 100644
index 000000000..8f1340cee
--- /dev/null
+++ b/web-docs/reference/specifications/protos.md
@@ -0,0 +1,432 @@
+
+# Protocol Documentation
+
+
+
+## schema/v1/schema.proto
+Flag evaluation API
+
+This proto forms the basis of a flag-evaluation API.
+It supports single and bulk evaluation RPCs, and flags of various types, as well as establishing a stream for getting notifications about changes in a flag definition.
+It supports the inclusion of a "context" with each evaluation, which may contain arbitraty attributes relevant to flag evaluation.
+
+
+
+
+### AnyFlag
+A variant type flag response.
+
+
+| Field | Type | Label | Description |
+| ----- | ---- | ----- | ----------- |
+| reason | [string](#string) | | The reason for the given return value, see https://openfeature.dev/docs/specification/types#resolution-details |
+| variant | [string](#string) | | The variant name of the returned flag value. |
+| bool_value | [bool](#bool) | | |
+| string_value | [string](#string) | | |
+| double_value | [double](#double) | | |
+| object_value | [google.protobuf.Struct](#google-protobuf-Struct) | | |
+
+
+
+
+
+
+
+
+### EventStreamRequest
+Empty stream request body
+
+
+
+
+
+
+
+
+### EventStreamResponse
+Response body for the EventStream stream response
+
+
+| Field | Type | Label | Description |
+| ----- | ---- | ----- | ----------- |
+| type | [string](#string) | | String key indicating the type of event that is being received, for example, provider_ready or configuration_change |
+| data | [google.protobuf.Struct](#google-protobuf-Struct) | | Object structure for use when sending relevant metadata to provide context to the event. Can be left unset when it is not required. |
+
+
+
+
+
+
+
+
+### ResolveAllRequest
+Request body for bulk flag evaluation, used by the ResolveAll rpc.
+
+
+| Field | Type | Label | Description |
+| ----- | ---- | ----- | ----------- |
+| context | [google.protobuf.Struct](#google-protobuf-Struct) | | Object structure describing the EvaluationContext used in the flag evaluation, see https://openfeature.dev/docs/reference/concepts/evaluation-context |
+
+
+
+
+
+
+
+
+### ResolveAllResponse
+Response body for bulk flag evaluation, used by the ResolveAll rpc.
+
+
+| Field | Type | Label | Description |
+| ----- | ---- | ----- | ----------- |
+| flags | [ResolveAllResponse.FlagsEntry](#schema-v1-ResolveAllResponse-FlagsEntry) | repeated | Object structure describing the evaluated flags for the provided context. |
+
+
+
+
+
+
+
+
+### ResolveAllResponse.FlagsEntry
+
+
+
+| Field | Type | Label | Description |
+| ----- | ---- | ----- | ----------- |
+| key | [string](#string) | | |
+| value | [AnyFlag](#schema-v1-AnyFlag) | | |
+
+
+
+
+
+
+
+
+### ResolveBooleanRequest
+Request body for boolean flag evaluation, used by the ResolveBoolean rpc.
+
+
+| Field | Type | Label | Description |
+| ----- | ---- | ----- | ----------- |
+| flag_key | [string](#string) | | Flag key of the requested flag. |
+| context | [google.protobuf.Struct](#google-protobuf-Struct) | | Object structure describing the EvaluationContext used in the flag evaluation, see https://openfeature.dev/docs/reference/concepts/evaluation-context |
+
+
+
+
+
+
+
+
+### ResolveBooleanResponse
+Response body for boolean flag evaluation. used by the ResolveBoolean rpc.
+
+
+| Field | Type | Label | Description |
+| ----- | ---- | ----- | ----------- |
+| value | [bool](#bool) | | The response value of the boolean flag evaluation, will be unset in the case of error. |
+| reason | [string](#string) | | The reason for the given return value, see https://openfeature.dev/docs/specification/types#resolution-details |
+| variant | [string](#string) | | The variant name of the returned flag value. |
+| metadata | [google.protobuf.Struct](#google-protobuf-Struct) | | Metadata for this evaluation |
+
+
+
+
+
+
+
+
+### ResolveFloatRequest
+Request body for float flag evaluation, used by the ResolveFloat rpc.
+
+
+| Field | Type | Label | Description |
+| ----- | ---- | ----- | ----------- |
+| flag_key | [string](#string) | | Flag key of the requested flag. |
+| context | [google.protobuf.Struct](#google-protobuf-Struct) | | Object structure describing the EvaluationContext used in the flag evaluation, see https://openfeature.dev/docs/reference/concepts/evaluation-context |
+
+
+
+
+
+
+
+
+### ResolveFloatResponse
+Response body for float flag evaluation. used by the ResolveFloat rpc.
+
+
+| Field | Type | Label | Description |
+| ----- | ---- | ----- | ----------- |
+| value | [double](#double) | | The response value of the float flag evaluation, will be empty in the case of error. |
+| reason | [string](#string) | | The reason for the given return value, see https://openfeature.dev/docs/specification/types#resolution-details |
+| variant | [string](#string) | | The variant name of the returned flag value. |
+| metadata | [google.protobuf.Struct](#google-protobuf-Struct) | | Metadata for this evaluation |
+
+
+
+
+
+
+
+
+### ResolveIntRequest
+Request body for int flag evaluation, used by the ResolveInt rpc.
+
+
+| Field | Type | Label | Description |
+| ----- | ---- | ----- | ----------- |
+| flag_key | [string](#string) | | Flag key of the requested flag. |
+| context | [google.protobuf.Struct](#google-protobuf-Struct) | | Object structure describing the EvaluationContext used in the flag evaluation, see https://openfeature.dev/docs/reference/concepts/evaluation-context |
+
+
+
+
+
+
+
+
+### ResolveIntResponse
+Response body for int flag evaluation. used by the ResolveInt rpc.
+
+
+| Field | Type | Label | Description |
+| ----- | ---- | ----- | ----------- |
+| value | [int64](#int64) | | The response value of the int flag evaluation, will be unset in the case of error. |
+| reason | [string](#string) | | The reason for the given return value, see https://openfeature.dev/docs/specification/types#resolution-details |
+| variant | [string](#string) | | The variant name of the returned flag value. |
+| metadata | [google.protobuf.Struct](#google-protobuf-Struct) | | Metadata for this evaluation |
+
+
+
+
+
+
+
+
+### ResolveObjectRequest
+Request body for object flag evaluation, used by the ResolveObject rpc.
+
+
+| Field | Type | Label | Description |
+| ----- | ---- | ----- | ----------- |
+| flag_key | [string](#string) | | Flag key of the requested flag. |
+| context | [google.protobuf.Struct](#google-protobuf-Struct) | | Object structure describing the EvaluationContext used in the flag evaluation, see https://openfeature.dev/docs/reference/concepts/evaluation-context |
+
+
+
+
+
+
+
+
+### ResolveObjectResponse
+Response body for object flag evaluation. used by the ResolveObject rpc.
+
+
+| Field | Type | Label | Description |
+| ----- | ---- | ----- | ----------- |
+| value | [google.protobuf.Struct](#google-protobuf-Struct) | | The response value of the object flag evaluation, will be unset in the case of error.
+
+NOTE: This structure will need to be decoded from google/protobuf/struct.proto before it is returned to the SDK |
+| reason | [string](#string) | | The reason for the given return value, see https://openfeature.dev/docs/specification/types#resolution-details |
+| variant | [string](#string) | | The variant name of the returned flag value. |
+| metadata | [google.protobuf.Struct](#google-protobuf-Struct) | | Metadata for this evaluation |
+
+
+
+
+
+
+
+
+### ResolveStringRequest
+Request body for string flag evaluation, used by the ResolveString rpc.
+
+
+| Field | Type | Label | Description |
+| ----- | ---- | ----- | ----------- |
+| flag_key | [string](#string) | | Flag key of the requested flag. |
+| context | [google.protobuf.Struct](#google-protobuf-Struct) | | Object structure describing the EvaluationContext used in the flag evaluation, see https://openfeature.dev/docs/reference/concepts/evaluation-context |
+
+
+
+
+
+
+
+
+### ResolveStringResponse
+Response body for string flag evaluation. used by the ResolveString rpc.
+
+
+| Field | Type | Label | Description |
+| ----- | ---- | ----- | ----------- |
+| value | [string](#string) | | The response value of the string flag evaluation, will be unset in the case of error. |
+| reason | [string](#string) | | The reason for the given return value, see https://openfeature.dev/docs/specification/types#resolution-details |
+| variant | [string](#string) | | The variant name of the returned flag value. |
+| metadata | [google.protobuf.Struct](#google-protobuf-Struct) | | Metadata for this evaluation |
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+### Service
+Service defines the exposed rpcs of flagd
+
+| Method Name | Request Type | Response Type | Description |
+| ----------- | ------------ | ------------- | ------------|
+| ResolveAll | [ResolveAllRequest](#schema-v1-ResolveAllRequest) | [ResolveAllResponse](#schema-v1-ResolveAllResponse) | |
+| ResolveBoolean | [ResolveBooleanRequest](#schema-v1-ResolveBooleanRequest) | [ResolveBooleanResponse](#schema-v1-ResolveBooleanResponse) | |
+| ResolveString | [ResolveStringRequest](#schema-v1-ResolveStringRequest) | [ResolveStringResponse](#schema-v1-ResolveStringResponse) | |
+| ResolveFloat | [ResolveFloatRequest](#schema-v1-ResolveFloatRequest) | [ResolveFloatResponse](#schema-v1-ResolveFloatResponse) | |
+| ResolveInt | [ResolveIntRequest](#schema-v1-ResolveIntRequest) | [ResolveIntResponse](#schema-v1-ResolveIntResponse) | |
+| ResolveObject | [ResolveObjectRequest](#schema-v1-ResolveObjectRequest) | [ResolveObjectResponse](#schema-v1-ResolveObjectResponse) | |
+| EventStream | [EventStreamRequest](#schema-v1-EventStreamRequest) | [EventStreamResponse](#schema-v1-EventStreamResponse) stream | |
+
+
+
+
+
+
+
+
+## sync/v1/sync_service.proto
+Flag definition sync API
+
+This proto defines a simple API to synchronize a feature flag definition.
+It supports establishing a stream for getting notifications about changes in a flag definition.
+
+
+
+
+### FetchAllFlagsRequest
+FetchAllFlagsRequest is the request to fetch all flags. Flagd sends this request as the client in order to resync its internal state
+
+
+| Field | Type | Label | Description |
+| ----- | ---- | ----- | ----------- |
+| provider_id | [string](#string) | | Optional: A unique identifier for flagd(grpc client) initiating the request. The server implementations may utilize this identifier to uniquely identify, validate(ex:- enforce authentication/authorization) and filter flag configurations that it can expose to this request. This field is intended to be optional. However server implementations may enforce it. ex:- provider_id: flagd-weatherapp-sidecar |
+| selector | [string](#string) | | Optional: A selector for the flag configuration request. The server implementation may utilize this to select flag configurations from a collection, select the source of the flag or combine this to any desired underlying filtering mechanism. ex:- selector: 'source=database,app=weatherapp' |
+
+
+
+
+
+
+
+
+### FetchAllFlagsResponse
+FetchAllFlagsResponse is the server response containing feature flag configurations
+
+
+| Field | Type | Label | Description |
+| ----- | ---- | ----- | ----------- |
+| flag_configuration | [string](#string) | | flagd feature flag configuration. Must be validated to schema - https://raw.githubusercontent.com/open-feature/schemas/main/json/flagd-definitions.json |
+
+
+
+
+
+
+
+
+### SyncFlagsRequest
+SyncFlagsRequest is the request initiating the sever-streaming rpc. Flagd sends this request, acting as the client
+
+
+| Field | Type | Label | Description |
+| ----- | ---- | ----- | ----------- |
+| provider_id | [string](#string) | | Optional: A unique identifier for flagd(grpc client) initiating the request. The server implementations may utilize this identifier to uniquely identify, validate(ex:- enforce authentication/authorization) and filter flag configurations that it can expose to this request. This field is intended to be optional. However server implementations may enforce it. ex:- provider_id: flagd-weatherapp-sidecar |
+| selector | [string](#string) | | Optional: A selector for the flag configuration request. The server implementation may utilize this to select flag configurations from a collection, select the source of the flag or combine this to any desired underlying filtering mechanism. ex:- selector: 'source=database,app=weatherapp' |
+
+
+
+
+
+
+
+
+### SyncFlagsResponse
+SyncFlagsResponse is the server response containing feature flag configurations and the state
+
+
+| Field | Type | Label | Description |
+| ----- | ---- | ----- | ----------- |
+| flag_configuration | [string](#string) | | flagd feature flag configuration. Must be validated to schema - https://raw.githubusercontent.com/open-feature/schemas/main/json/flagd-definitions.json |
+| state | [SyncState](#sync-v1-SyncState) | | State conveying the operation to be performed by flagd. See the descriptions of SyncState for an explanation of supported values |
+
+
+
+
+
+
+
+
+
+
+### SyncState
+SyncState conveys the state of the payload. These states are related to flagd isync.go type definitions but
+contains extras to optimize grpc use case. Refer - https://github.com/open-feature/flagd/blob/main/pkg/sync/isync.go
+
+| Name | Number | Description |
+| ---- | ------ | ----------- |
+| SYNC_STATE_UNSPECIFIED | 0 | Value is ignored by the listening flagd |
+| SYNC_STATE_ALL | 1 | All the flags matching the request. This is the default response and other states can be ignored by the implementation. Flagd internally replaces all existing flags for this response state. |
+| SYNC_STATE_ADD | 2 | Convey an addition of a flag. Flagd internally handles this by combining new flags with existing ones |
+| SYNC_STATE_UPDATE | 3 | Convey an update of a flag. Flagd internally attempts to update if the updated flag already exist OR if it does not, it will get added |
+| SYNC_STATE_DELETE | 4 | Convey a deletion of a flag. Flagd internally removes the flag |
+| SYNC_STATE_PING | 5 | Optional server ping to check client connectivity. Handling is ignored by flagd and is to merely support live check |
+
+
+
+
+
+
+
+
+
+### FlagSyncService
+FlagService implements a server streaming to provide realtime flag configurations
+
+| Method Name | Request Type | Response Type | Description |
+| ----------- | ------------ | ------------- | ------------|
+| SyncFlags | [SyncFlagsRequest](#sync-v1-SyncFlagsRequest) | [SyncFlagsResponse](#sync-v1-SyncFlagsResponse) stream | |
+| FetchAllFlags | [FetchAllFlagsRequest](#sync-v1-FetchAllFlagsRequest) | [FetchAllFlagsResponse](#sync-v1-FetchAllFlagsResponse) | |
+
+
+
+
+
+## Scalar Value Types
+
+| .proto Type | Notes | C++ | Java | Python | Go | C# | PHP | Ruby |
+| ----------- | ----- | --- | ---- | ------ | -- | -- | --- | ---- |
+| double | | double | double | float | float64 | double | float | Float |
+| float | | float | float | float | float32 | float | float | Float |
+| int32 | Uses variable-length encoding. Inefficient for encoding negative numbers – if your field is likely to have negative values, use sint32 instead. | int32 | int | int | int32 | int | integer | Bignum or Fixnum (as required) |
+| int64 | Uses variable-length encoding. Inefficient for encoding negative numbers – if your field is likely to have negative values, use sint64 instead. | int64 | long | int/long | int64 | long | integer/string | Bignum |
+| uint32 | Uses variable-length encoding. | uint32 | int | int/long | uint32 | uint | integer | Bignum or Fixnum (as required) |
+| uint64 | Uses variable-length encoding. | uint64 | long | int/long | uint64 | ulong | integer/string | Bignum or Fixnum (as required) |
+| sint32 | Uses variable-length encoding. Signed int value. These more efficiently encode negative numbers than regular int32s. | int32 | int | int | int32 | int | integer | Bignum or Fixnum (as required) |
+| sint64 | Uses variable-length encoding. Signed int value. These more efficiently encode negative numbers than regular int64s. | int64 | long | int/long | int64 | long | integer/string | Bignum |
+| fixed32 | Always four bytes. More efficient than uint32 if values are often greater than 2^28. | uint32 | int | int | uint32 | uint | integer | Bignum or Fixnum (as required) |
+| fixed64 | Always eight bytes. More efficient than uint64 if values are often greater than 2^56. | uint64 | long | int/long | uint64 | ulong | integer/string | Bignum |
+| sfixed32 | Always four bytes. | int32 | int | int | int32 | int | integer | Bignum or Fixnum (as required) |
+| sfixed64 | Always eight bytes. | int64 | long | int/long | int64 | long | integer/string | Bignum |
+| bool | | bool | boolean | boolean | bool | bool | boolean | TrueClass/FalseClass |
+| string | A string must always contain UTF-8 encoded or 7-bit ASCII text. | string | String | str/unicode | string | string | string | String (UTF-8) |
+| bytes | May contain any arbitrary sequence of bytes. | string | ByteString | str | []byte | ByteString | string | String (ASCII-8BIT) |
+
diff --git a/web-docs/reference/specifications/rpc-providers.md b/web-docs/reference/specifications/rpc-providers.md
new file mode 100644
index 000000000..404cc8d79
--- /dev/null
+++ b/web-docs/reference/specifications/rpc-providers.md
@@ -0,0 +1,122 @@
+# Creating an RPC flagd provider
+
+By default, **flagd** is a remote service that is accessed via **grpc** by a client application to retrieve feature flags.
+Depending on the environment, flagd therefore is usually deployed as a standalone service, e.g. as a Kubernetes Deployment,
+or injected as a sidecar container into the pod running the client application,
+as it is done in the [OpenFeature Operator](https://github.com/open-feature/open-feature-operator).
+
+Prerequisites:
+
+- Understanding of [general provider concepts](https://openfeature.dev/docs/reference/concepts/provider/)
+- Proficiency in the chosen programming language (check the language isn't already covered by the [existing providers](../usage/flagd_providers.md))
+
+## flagd Evaluation API
+
+Fundamentally, RPC providers use the [evaluation schema](./protos.md#schemav1schemaproto) to connect to flagd, initiate evaluation RPCs, and listen for changes in the flag definitions.
+In order to do this, you must generate the gRPC primitives (message types and client) using the protobuf code generation mechanisms available in your language.
+If you are unable to use gRPC code generation, you can also use REST (via the [connect protocol](https://buf.build/blog/connect-a-better-grpc)) to communivate with flagd, though in this case, you will not be able to open a stream to listen for changes.
+
+### Protobuf
+
+Protobuf schemas define the contract between the flagd evaluation API and a client.
+
+#### Code generation for gRPC sync
+
+Leverage the [buf CLI](https://docs.buf.build/installation) or protoc to generate a `flagd-proxy` client in the chosen technology:
+
+Add the [open-feature schema repository](https://github.com/open-feature/schemas) as a submodule
+
+```shell
+git submodule add --force https://github.com/open-feature/schemas.git
+```
+
+Create a `buf.gen.{chosen language}.yaml` for the chosen language in `schemas/protobuf` (if it doesn't already exist) using one of the other files as a template (find a plugin for the chosen language [here](https://buf.build/protocolbuffers/plugins)) and create a pull request with this file.
+
+Generate the code (this step ought to be automated in the build process for the chosen technology so that the generated code is never committed)
+
+```shell
+cd schemas/protobuf
+buf generate --template buf.gen.{chosen language}.yaml
+```
+
+As an alternative to buf, use the .proto file directly along with whatever protoc-related tools or plugins avaialble for your language.
+
+Move the generated code (following convention for the chosen language) and add its location to .gitignore
+
+Note that for the in-process provider only the `schema` package will be relevant, since RPC providers communicate directly to flagd.
+
+## Provider lifecycle, initialization and shutdown
+
+With the release of the v0.6.0 spec, OpenFeature now outlines a lifecycle for in-process flagd provider initialization and shutdown.
+
+In-process flagd providers should do the following to make use of OpenFeature v0.6.0 features:
+
+- start in a `NOT_READY` state
+- fetch the flag definition specified in the sync provider sources and set `state` to `READY` or `ERROR` in the `initialization` function
+ - note that the SDK will automatically emit `PROVIDER_READY`/`PROVIDER_ERROR` according to the termination of the `initialization` function
+- throw an exception or terminate abnormally if a connection cannot be established during `initialization`
+- For gRPC based sources (i.e. flagd-proxy), attempt to restore the streaming connection to flagd-proxy (if the connection cannot be established or is broken):
+ - If flag definition have been retrieved previously, go into `STALE` state to indicate that flag resolution responsees are based on potentially outdated Flag definition.
+ - reconnection should be attempted with an exponential back-off, with a max-delay of `maxSyncRetryInterval` (see [configuration](#configuration))
+ - reconnection should be attempted up to `maxSyncRetryDelay` times (see [configuration](#configuration))
+ - `PROVIDER_READY` and `PROVIDER_CONFIGURATION_CHANGED` should be emitted, in that order, after successful reconnection
+- For Kubernetes sync sources, retry to retrieve the FlagConfiguration resource, using an exponential back-off strategy, with a max-delay of `maxSyncRetryInterval` (see [configuration](#configuration))
+- emit `PROVIDER_CONFIGURATION_CHANGED` event and update ruleset when a `configuration_change` message is received on the streaming connection
+- close the streaming connection in the`shutdown` function
+
+```mermaid
+stateDiagram-v2
+ [*] --> NOT_READY
+ NOT_READY --> READY: initialize(), connection to flagd established, stream connected
+ NOT_READY --> ERROR: initialize(), unable to connect or establish stream(retry)
+ READY --> ERROR: stream or connection disconnected
+ READY --> READY: configuration_change (emit changed*)
+ ERROR --> READY: reconnect successful (emit ready*, changed*)
+ ERROR --> ERROR: maxSyncRetries reached
+ ERROR --> [*]: shutdown(), stream disconnected
+```
+
+\* ready=`PROVIDER_READY`, changed=`PROVIDER_CONFIGURATION_CHANGED`, stale=`PROVIDER_STALE`, error=`PROVIDER_ERROR`
+
+## Configuration
+
+Expose means to configure the provider aligned with the following priority system (highest to lowest).
+
+```mermaid
+flowchart LR
+ constructor-parameters -->|highest priority| environment-variables -->|lowest priority| defaults
+```
+
+### Explicit declaration
+
+This takes the form of parameters to the provider's constructor, it has the highest priority.
+
+### Environment variables
+
+Read environment variables with sensible defaults (before applying the values explicitly declared to the constructor).
+
+| Option name | Environment variable name | Type & Values | Default |
+|-----------------------|--------------------------------|------------------------|-----------|
+| host | FLAGD_HOST | String | localhost |
+| port | FLAGD_PORT | int | 8013 |
+| tls | FLAGD_TLS | boolean | false |
+| socketPath | FLAGD_SOCKET_PATH | String | null |
+| certPath | FLAGD_SERVER_CERT_PATH | String | null |
+| deadline | FLAGD_DEADLINE_MS | int | 500 |
+| cache | FLAGD_CACHE | String - lru, disabled | lru |
+| maxCacheSize | FLAGD_MAX_CACHE_SIZE | int | 1000 |
+| maxEventStreamRetries | FLAGD_MAX_EVENT_STREAM_RETRIES | int | 5 |
+| retryBackoffMs | FLAGD_RETRY_BACKOFF_MS | int | 1000 |
+
+## Error handling
+
+Handle flag evaluation errors by using the error constructors exported by the SDK (e.g. `openfeature.NewProviderNotReadyResolutionError(ConnectionError)`), thereby allowing the SDK to parse and handle the error appropriately.
+
+## Post creation
+
+The following steps will extend the reach of the newly created provider to other developers of the chosen technology.
+
+### Open an issue to document the provider
+
+Create an issue in openfeature.dev [here](https://github.com/open-feature/openfeature.dev/issues/new?assignees=&labels=provider&template=document-provider.yaml&title=%5BProvider%5D%3A+).
+This will ensure the provider is added to OpenFeature's website.
diff --git a/web-docs/reference/sync-configuration.md b/web-docs/reference/sync-configuration.md
new file mode 100644
index 000000000..089cf8f4d
--- /dev/null
+++ b/web-docs/reference/sync-configuration.md
@@ -0,0 +1,82 @@
+# Sync configuration
+
+See [syncs](../concepts/syncs.md) for a conceptual overview.
+
+## URI patterns
+
+Any URI passed to flagd via the `--uri` (`-f`) flag must follow one of the 4 following patterns with prefixes to ensure that
+it is passed to the correct implementation:
+
+| Implied Sync Provider | Prefix | Example |
+| --------------------- | ---------------------- | ------------------------------------- |
+| `kubernetes` | `core.openfeature.dev` | `core.openfeature.dev/default/my-crd` |
+| `file` | `file:` | `file:etc/flagd/my-flags.json` |
+| `http` | `http(s)://` | `https://my-flags.com/flags` |
+| `grpc` | `grpc(s)://` | `grpc://my-flags-server` |
+
+## Source Configuration
+
+While a URI may be passed to flagd via the `--uri` (`-f`) flag, some implementations may require further configurations.
+In these cases the `--sources` flag should be used.
+
+The flagd accepts a string argument, which should be a JSON representation of an array of `SourceConfig` objects.
+
+Alternatively, these configurations can be passed to flagd via config file, specified using the `--config` flag.
+
+| Field | Type | Note |
+| ----------- | ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------ |
+| uri | required `string` | Flag configuration source of the sync |
+| provider | required `string` | Provider type - `file`, `kubernetes`, `http` or `grpc` |
+| bearerToken | optional `string` | Used for http sync; token gets appended to `Authorization` header with [bearer schema](https://www.rfc-editor.org/rfc/rfc6750#section-2.1) |
+| interval | optional `uint32` | Used for http sync; requests will be made at this interval. Defaults to 5 seconds. |
+| tls | optional `boolean` | Enable/Disable secure TLS connectivity. Currently used only by gRPC sync. Default(ex:- if unset) is false, which will use an insecure connection |
+| providerID | optional `string` | Value binds to grpc connection's providerID field. gRPC server implementations may use this to identify connecting flagd instance |
+| selector | optional `string` | Value binds to grpc connection's selector field. gRPC server implementations may use this to filter flag configurations |
+| certPath | optional `string` | Used for grpcs sync when TLS certificate is needed. If not provided, system certificates will be used for TLS connection |
+
+The `uri` field values **do not** follow the [URI patterns](#uri-patterns). The provider type is instead derived
+from the `provider` field. Only exception is the remote provider where `http(s)://` is expected by default. Incorrect
+URIs will result in a flagd start-up failure with errors from the respective sync provider implementation.
+
+Given below are example sync providers, startup command and equivalent config file definition:
+
+Sync providers:
+
+- `file` - config/samples/example_flags.json
+- `http` -
+- `https` -
+- `kubernetes` - default/my-flag-config
+- `grpc`(insecure) - grpc-source:8080
+- `grpcs`(secure) - my-flag-source:8080
+
+Startup command:
+
+```sh
+./bin/flagd start
+--sources='[{"uri":"config/samples/example_flags.json","provider":"file"},
+ {"uri":"http://my-flag-source.json","provider":"http","bearerToken":"bearer-dji34ld2l"},
+ {"uri":"default/my-flag-config","provider":"kubernetes"},
+ {"uri":"grpc-source:8080","provider":"grpc"},
+ {"uri":"my-flag-source:8080","provider":"grpc", "certPath": "/certs/ca.cert", "tls": true, "providerID": "flagd-weatherapp-sidecar", "selector": "source=database,app=weatherapp"}]'
+```
+
+Configuration file,
+
+```yaml
+sources:
+ - uri: config/samples/example_flags.json
+ provider: file
+ - uri: http://my-flag-source.json
+ provider: http
+ bearerToken: bearer-dji34ld2l
+ - uri: default/my-flag-config
+ provider: kubernetes
+ - uri: my-flag-source:8080
+ provider: grpc
+ - uri: my-flag-source:8080
+ provider: grpc
+ certPath: /certs/ca.cert
+ tls: true
+ providerID: flagd-weatherapp-sidecar
+ selector: 'source=database,app=weatherapp'
+```
diff --git a/web-docs/troubleshooting.md b/web-docs/troubleshooting.md
index 7d99a8f1a..2fe15df26 100644
--- a/web-docs/troubleshooting.md
+++ b/web-docs/troubleshooting.md
@@ -1,6 +1,18 @@
# Troubleshooting flagd
-## HTTP(S) Service Integer Response Behavior
+## Debugging Evaluations
+
+If a flag or targeting rule isn't proceeding the way you'd expect, you may want to enable more verbose logging.
+
+flagd and flagd providers typically have debug or verbose logging modes that you can use for this sort of troubleshooting.
+You can do this in the standalone version of flagd by starting it with the `--debug` flag (see [CLI](./reference/flagd-cli/flagd/flagd.md) for more information).
+
+_In-process_ providers which embed the flag evaluation engine use a logging consistent with their implementation language and SDK.
+See your provider's documentation for details on how to enable verbose logging.
+
+The [detailed evaluation](https://openfeature.dev/docs/reference/concepts/evaluation-api#detailed-evaluation) functions can also be helpful in understanding why an evaluation proceeded a particular way.
+
+## HTTP Integer Response Behavior
Why is my `int` response a `string`?
Command:
@@ -15,7 +27,7 @@ Result:
{"value":"1","reason":"DEFAULT","variant":"one"}
```
-When interacting directly with the flagD http(s) api and requesting an `int` the response type will be a `string`.
+When interacting directly with the flagd HTTP api and requesting an `int` the response type will be a `string`.
This behaviour is introduced by [grpc-gateway](https://github.com/grpc-ecosystem/grpc-gateway), which uses [proto3 json mapping](https://developers.google.com/protocol-buffers/docs/proto3#json) to build the response object.
If a number value is required, and none of the provided SDK's can be used, then it is recommended to use the `float64` endpoint instead: