feat(ffe): expose observeFullEvaluationData config-level FFI getter - #2373
Conversation
Note to self: Follow-ups to propagate to SDK reposThis PR adds the
Other language SDKs to checkThe same getter should be exposed by the other libdatadog FFI consumers once they pick up the release:
|
🎉 All green!🧪 All tests passed 🎯 Code Coverage (details) 🔗 Commit SHA: f1baf07 | Docs | View more details | Give us feedback! |
BenchmarksComparisonBenchmark execution time: 2026-08-20 15:11:49 Comparing candidate commit f1baf07 in PR branch Found 0 performance improvements and 3 performance regressions! Performance is the same for 11 metrics, 0 unstable metrics.
|
| cpu_model | git_commit_sha | git_commit_date | git_branch |
|---|---|---|---|
| Intel(R) Xeon(R) Platinum 8259CL CPU @ 2.50GHz | f1baf07 | 1787237900 | vickie/ffl-3038-add-observe_full_evaluation_data-accessor |
| scenario | metric | min | mean ± sd | median ± mad | p75 | p95 | p99 | max | peak_to_median_ratio | skewness | kurtosis | cv | sem | runs | sample_size |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| flagevaluation_evp/coalescer/scale/2500flags_500users_20fields | execution_time | 5.399ms | 5.415ms ± 0.007ms | 5.415ms ± 0.004ms | 5.419ms | 5.426ms | 5.430ms | 5.432ms | 0.31% | 0.001 | -0.398 | 0.12% | 0.000ms | 1 | 200 |
| flagevaluation_evp/coalescer/scale/2500flags_500users_20fields | throughput | 460270.402op/s | 461691.308op/s ± 558.215op/s | 461681.988op/s ± 380.399op/s | 462063.100op/s | 462652.001op/s | 462846.579op/s | 463023.542op/s | 0.29% | 0.004 | -0.399 | 0.12% | 39.472op/s | 1 | 200 |
| flagevaluation_evp/coalescer/stress/10flags_1000users_250fields | execution_time | 7.938ms | 7.951ms ± 0.008ms | 7.950ms ± 0.003ms | 7.954ms | 7.960ms | 7.992ms | 8.008ms | 0.73% | 3.625 | 19.694 | 0.11% | 0.001ms | 1 | 200 |
| flagevaluation_evp/coalescer/stress/10flags_1000users_250fields | throughput | 124880.323op/s | 125771.118op/s ± 132.557op/s | 125792.778op/s ± 53.677op/s | 125840.196op/s | 125909.280op/s | 125967.047op/s | 125983.009op/s | 0.15% | -3.598 | 19.476 | 0.11% | 9.373op/s | 1 | 200 |
| flagevaluation_evp/coalescer/typical/100flags_50users_10fields | execution_time | 180.008µs | 185.268µs ± 38.810µs | 182.406µs ± 0.252µs | 182.746µs | 183.505µs | 184.004µs | 731.321µs | 300.93% | 14.031 | 194.913 | 20.90% | 2.744µs | 1 | 200 |
| flagevaluation_evp/coalescer/typical/100flags_50users_10fields | throughput | 136738.860op/s | 545824.351op/s ± 29125.388op/s | 548226.955op/s ± 757.517op/s | 548838.721op/s | 549492.275op/s | 553253.855op/s | 555530.248op/s | 1.33% | -13.959 | 193.559 | 5.32% | 2059.476op/s | 1 | 200 |
| scenario | metric | 95% CI mean | Shapiro-Wilk pvalue | Ljung-Box pvalue (lag=1) | Dip test pvalue |
|---|---|---|---|---|---|
| flagevaluation_evp/coalescer/scale/2500flags_500users_20fields | execution_time | [5.414ms; 5.416ms] or [-0.017%; +0.017%] | None | None | None |
| flagevaluation_evp/coalescer/scale/2500flags_500users_20fields | throughput | [461613.944op/s; 461768.671op/s] or [-0.017%; +0.017%] | None | None | None |
| flagevaluation_evp/coalescer/stress/10flags_1000users_250fields | execution_time | [7.950ms; 7.952ms] or [-0.015%; +0.015%] | None | None | None |
| flagevaluation_evp/coalescer/stress/10flags_1000users_250fields | throughput | [125752.747op/s; 125789.489op/s] or [-0.015%; +0.015%] | None | None | None |
| flagevaluation_evp/coalescer/typical/100flags_50users_10fields | execution_time | [179.889µs; 190.646µs] or [-2.903%; +2.903%] | None | None | None |
| flagevaluation_evp/coalescer/typical/100flags_50users_10fields | throughput | [541787.853op/s; 549860.850op/s] or [-0.740%; +0.740%] | None | None | None |
Group 2
| cpu_model | git_commit_sha | git_commit_date | git_branch |
|---|---|---|---|
| Intel(R) Xeon(R) Platinum 8259CL CPU @ 2.50GHz | f1baf07 | 1787237900 | vickie/ffl-3038-add-observe_full_evaluation_data-accessor |
| scenario | metric | min | mean ± sd | median ± mad | p75 | p95 | p99 | max | peak_to_median_ratio | skewness | kurtosis | cv | sem | runs | sample_size |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| single_flag_killswitch/rules-based | execution_time | 156.723ns | 159.792ns ± 2.413ns | 159.289ns ± 1.318ns | 160.848ns | 164.147ns | 166.964ns | 169.920ns | 6.67% | 1.227 | 1.697 | 1.51% | 0.171ns | 1 | 200 |
| scenario | metric | 95% CI mean | Shapiro-Wilk pvalue | Ljung-Box pvalue (lag=1) | Dip test pvalue |
|---|---|---|---|---|---|
| single_flag_killswitch/rules-based | execution_time | [159.457ns; 160.126ns] or [-0.209%; +0.209%] | None | None | None |
Group 3
| cpu_model | git_commit_sha | git_commit_date | git_branch |
|---|---|---|---|
| Intel(R) Xeon(R) Platinum 8259CL CPU @ 2.50GHz | f1baf07 | 1787237900 | vickie/ffl-3038-add-observe_full_evaluation_data-accessor |
| scenario | metric | min | mean ± sd | median ± mad | p75 | p95 | p99 | max | peak_to_median_ratio | skewness | kurtosis | cv | sem | runs | sample_size |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| flagevaluation_evp/payloads/scale/2500flags_500users_20fields | execution_time | 21.791ms | 21.892ms ± 0.040ms | 21.892ms ± 0.024ms | 21.914ms | 21.966ms | 21.981ms | 22.003ms | 0.51% | 0.183 | 0.053 | 0.18% | 0.003ms | 1 | 200 |
| flagevaluation_evp/payloads/scale/2500flags_500users_20fields | throughput | 113621.456op/s | 114196.084op/s ± 208.615op/s | 114197.228op/s ± 124.331op/s | 114323.732op/s | 114564.847op/s | 114663.358op/s | 114726.658op/s | 0.46% | -0.172 | 0.051 | 0.18% | 14.751op/s | 1 | 200 |
| flagevaluation_evp/payloads/stress/10flags_1000users_250fields | execution_time | 102.187ms | 102.839ms ± 0.346ms | 102.844ms ± 0.233ms | 103.062ms | 103.349ms | 103.491ms | 104.780ms | 1.88% | 0.797 | 3.624 | 0.34% | 0.024ms | 1 | 200 |
| flagevaluation_evp/payloads/stress/10flags_1000users_250fields | throughput | 9543.828op/s | 9724.067op/s ± 32.599op/s | 9723.460op/s ± 21.940op/s | 9746.972op/s | 9773.054op/s | 9783.643op/s | 9785.970op/s | 0.64% | -0.748 | 3.341 | 0.33% | 2.305op/s | 1 | 200 |
| flagevaluation_evp/payloads/typical/100flags_50users_10fields | execution_time | 596.601µs | 599.242µs ± 1.526µs | 598.780µs ± 1.246µs | 600.891µs | 601.550µs | 601.901µs | 602.036µs | 0.54% | 0.221 | -1.428 | 0.25% | 0.108µs | 1 | 200 |
| flagevaluation_evp/payloads/typical/100flags_50users_10fields | throughput | 166103.071op/s | 166878.567op/s ± 424.834op/s | 167006.185op/s ± 347.878op/s | 167238.423op/s | 167451.833op/s | 167554.974op/s | 167616.267op/s | 0.37% | -0.217 | -1.428 | 0.25% | 30.040op/s | 1 | 200 |
| scenario | metric | 95% CI mean | Shapiro-Wilk pvalue | Ljung-Box pvalue (lag=1) | Dip test pvalue |
|---|---|---|---|---|---|
| flagevaluation_evp/payloads/scale/2500flags_500users_20fields | execution_time | [21.887ms; 21.898ms] or [-0.025%; +0.025%] | None | None | None |
| flagevaluation_evp/payloads/scale/2500flags_500users_20fields | throughput | [114167.172op/s; 114224.996op/s] or [-0.025%; +0.025%] | None | None | None |
| flagevaluation_evp/payloads/stress/10flags_1000users_250fields | execution_time | [102.791ms; 102.887ms] or [-0.047%; +0.047%] | None | None | None |
| flagevaluation_evp/payloads/stress/10flags_1000users_250fields | throughput | [9719.549op/s; 9728.585op/s] or [-0.046%; +0.046%] | None | None | None |
| flagevaluation_evp/payloads/typical/100flags_50users_10fields | execution_time | [599.030µs; 599.454µs] or [-0.035%; +0.035%] | None | None | None |
| flagevaluation_evp/payloads/typical/100flags_50users_10fields | throughput | [166819.689op/s; 166937.444op/s] or [-0.035%; +0.035%] | None | None | None |
Group 4
| cpu_model | git_commit_sha | git_commit_date | git_branch |
|---|---|---|---|
| Intel(R) Xeon(R) Platinum 8259CL CPU @ 2.50GHz | f1baf07 | 1787237900 | vickie/ffl-3038-add-observe_full_evaluation_data-accessor |
| scenario | metric | min | mean ± sd | median ± mad | p75 | p95 | p99 | max | peak_to_median_ratio | skewness | kurtosis | cv | sem | runs | sample_size |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| sdk_test_data/rules-based | execution_time | 142.671µs | 145.905µs ± 5.834µs | 144.610µs ± 0.676µs | 145.645µs | 150.917µs | 168.367µs | 204.827µs | 41.64% | 7.253 | 61.899 | 3.99% | 0.412µs | 1 | 200 |
| scenario | metric | 95% CI mean | Shapiro-Wilk pvalue | Ljung-Box pvalue (lag=1) | Dip test pvalue |
|---|---|---|---|---|---|
| sdk_test_data/rules-based | execution_time | [145.096µs; 146.713µs] or [-0.554%; +0.554%] | None | None | None |
Baseline
Baseline benchmark details
Group 1
| cpu_model | git_commit_sha | git_commit_date | git_branch |
|---|---|---|---|
| Intel(R) Xeon(R) Platinum 8259CL CPU @ 2.50GHz | 24022a9 | 1787233149 | main |
| scenario | metric | min | mean ± sd | median ± mad | p75 | p95 | p99 | max | peak_to_median_ratio | skewness | kurtosis | cv | sem | runs | sample_size |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| flagevaluation_evp/coalescer/scale/2500flags_500users_20fields | execution_time | 5.394ms | 5.414ms ± 0.008ms | 5.414ms ± 0.004ms | 5.418ms | 5.425ms | 5.431ms | 5.454ms | 0.74% | 0.596 | 3.409 | 0.14% | 0.001ms | 1 | 200 |
| flagevaluation_evp/coalescer/scale/2500flags_500users_20fields | throughput | 458337.573op/s | 461764.085op/s ± 649.141op/s | 461749.716op/s ± 359.687op/s | 462119.904op/s | 462808.942op/s | 463224.213op/s | 463446.685op/s | 0.37% | -0.574 | 3.319 | 0.14% | 45.901op/s | 1 | 200 |
| flagevaluation_evp/coalescer/stress/10flags_1000users_250fields | execution_time | 7.958ms | 7.973ms ± 0.007ms | 7.973ms ± 0.004ms | 7.976ms | 7.982ms | 8.005ms | 8.010ms | 0.47% | 1.936 | 7.490 | 0.09% | 0.000ms | 1 | 200 |
| flagevaluation_evp/coalescer/stress/10flags_1000users_250fields | throughput | 124842.735op/s | 125417.734op/s ± 109.556op/s | 125430.847op/s ± 58.044op/s | 125485.028op/s | 125550.964op/s | 125601.165op/s | 125656.687op/s | 0.18% | -1.921 | 7.410 | 0.09% | 7.747op/s | 1 | 200 |
| flagevaluation_evp/coalescer/typical/100flags_50users_10fields | execution_time | 181.249µs | 183.830µs ± 0.548µs | 183.702µs ± 0.210µs | 184.002µs | 184.937µs | 185.309µs | 186.316µs | 1.42% | 0.518 | 5.159 | 0.30% | 0.039µs | 1 | 200 |
| flagevaluation_evp/coalescer/typical/100flags_50users_10fields | throughput | 536723.998op/s | 543984.343op/s ± 1619.989op/s | 544358.857op/s ± 622.529op/s | 544878.338op/s | 545342.718op/s | 548185.545op/s | 551726.878op/s | 1.35% | -0.456 | 5.228 | 0.30% | 114.551op/s | 1 | 200 |
| scenario | metric | 95% CI mean | Shapiro-Wilk pvalue | Ljung-Box pvalue (lag=1) | Dip test pvalue |
|---|---|---|---|---|---|
| flagevaluation_evp/coalescer/scale/2500flags_500users_20fields | execution_time | [5.413ms; 5.415ms] or [-0.019%; +0.019%] | None | None | None |
| flagevaluation_evp/coalescer/scale/2500flags_500users_20fields | throughput | [461674.121op/s; 461854.050op/s] or [-0.019%; +0.019%] | None | None | None |
| flagevaluation_evp/coalescer/stress/10flags_1000users_250fields | execution_time | [7.972ms; 7.974ms] or [-0.012%; +0.012%] | None | None | None |
| flagevaluation_evp/coalescer/stress/10flags_1000users_250fields | throughput | [125402.551op/s; 125432.917op/s] or [-0.012%; +0.012%] | None | None | None |
| flagevaluation_evp/coalescer/typical/100flags_50users_10fields | execution_time | [183.754µs; 183.906µs] or [-0.041%; +0.041%] | None | None | None |
| flagevaluation_evp/coalescer/typical/100flags_50users_10fields | throughput | [543759.828op/s; 544208.858op/s] or [-0.041%; +0.041%] | None | None | None |
Group 2
| cpu_model | git_commit_sha | git_commit_date | git_branch |
|---|---|---|---|
| Intel(R) Xeon(R) Platinum 8259CL CPU @ 2.50GHz | 24022a9 | 1787233149 | main |
| scenario | metric | min | mean ± sd | median ± mad | p75 | p95 | p99 | max | peak_to_median_ratio | skewness | kurtosis | cv | sem | runs | sample_size |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| single_flag_killswitch/rules-based | execution_time | 155.856ns | 159.741ns ± 2.613ns | 159.260ns ± 1.656ns | 161.317ns | 164.691ns | 167.195ns | 168.960ns | 6.09% | 0.890 | 0.322 | 1.63% | 0.185ns | 1 | 200 |
| scenario | metric | 95% CI mean | Shapiro-Wilk pvalue | Ljung-Box pvalue (lag=1) | Dip test pvalue |
|---|---|---|---|---|---|
| single_flag_killswitch/rules-based | execution_time | [159.379ns; 160.103ns] or [-0.227%; +0.227%] | None | None | None |
Group 3
| cpu_model | git_commit_sha | git_commit_date | git_branch |
|---|---|---|---|
| Intel(R) Xeon(R) Platinum 8259CL CPU @ 2.50GHz | 24022a9 | 1787233149 | main |
| scenario | metric | min | mean ± sd | median ± mad | p75 | p95 | p99 | max | peak_to_median_ratio | skewness | kurtosis | cv | sem | runs | sample_size |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| flagevaluation_evp/payloads/scale/2500flags_500users_20fields | execution_time | 20.914ms | 21.035ms ± 0.060ms | 21.025ms ± 0.036ms | 21.066ms | 21.145ms | 21.247ms | 21.278ms | 1.20% | 1.192 | 2.284 | 0.29% | 0.004ms | 1 | 200 |
| flagevaluation_evp/payloads/scale/2500flags_500users_20fields | throughput | 117491.967op/s | 118848.336op/s ± 340.261op/s | 118905.482op/s ± 205.072op/s | 119081.403op/s | 119270.048op/s | 119394.142op/s | 119539.227op/s | 0.53% | -1.168 | 2.195 | 0.29% | 24.060op/s | 1 | 200 |
| flagevaluation_evp/payloads/stress/10flags_1000users_250fields | execution_time | 95.334ms | 95.784ms ± 0.297ms | 95.854ms ± 0.153ms | 95.974ms | 96.059ms | 96.110ms | 98.208ms | 2.46% | 2.454 | 20.303 | 0.31% | 0.021ms | 1 | 200 |
| flagevaluation_evp/payloads/stress/10flags_1000users_250fields | throughput | 10182.420op/s | 10440.205op/s ± 32.100op/s | 10432.499op/s ± 16.628op/s | 10473.142op/s | 10481.122op/s | 10484.165op/s | 10489.463op/s | 0.55% | -2.307 | 18.824 | 0.31% | 2.270op/s | 1 | 200 |
| flagevaluation_evp/payloads/typical/100flags_50users_10fields | execution_time | 577.619µs | 580.269µs ± 1.252µs | 580.372µs ± 0.942µs | 581.146µs | 582.405µs | 583.108µs | 583.547µs | 0.55% | 0.092 | -0.624 | 0.22% | 0.089µs | 1 | 200 |
| flagevaluation_evp/payloads/typical/100flags_50users_10fields | throughput | 171365.691op/s | 172334.603op/s ± 371.778op/s | 172303.193op/s ± 279.636op/s | 172626.423op/s | 172913.165op/s | 173075.221op/s | 173124.356op/s | 0.48% | -0.083 | -0.630 | 0.22% | 26.289op/s | 1 | 200 |
| scenario | metric | 95% CI mean | Shapiro-Wilk pvalue | Ljung-Box pvalue (lag=1) | Dip test pvalue |
|---|---|---|---|---|---|
| flagevaluation_evp/payloads/scale/2500flags_500users_20fields | execution_time | [21.027ms; 21.044ms] or [-0.040%; +0.040%] | None | None | None |
| flagevaluation_evp/payloads/scale/2500flags_500users_20fields | throughput | [118801.179op/s; 118895.493op/s] or [-0.040%; +0.040%] | None | None | None |
| flagevaluation_evp/payloads/stress/10flags_1000users_250fields | execution_time | [95.743ms; 95.826ms] or [-0.043%; +0.043%] | None | None | None |
| flagevaluation_evp/payloads/stress/10flags_1000users_250fields | throughput | [10435.756op/s; 10444.653op/s] or [-0.043%; +0.043%] | None | None | None |
| flagevaluation_evp/payloads/typical/100flags_50users_10fields | execution_time | [580.096µs; 580.443µs] or [-0.030%; +0.030%] | None | None | None |
| flagevaluation_evp/payloads/typical/100flags_50users_10fields | throughput | [172283.079op/s; 172386.128op/s] or [-0.030%; +0.030%] | None | None | None |
Group 4
| cpu_model | git_commit_sha | git_commit_date | git_branch |
|---|---|---|---|
| Intel(R) Xeon(R) Platinum 8259CL CPU @ 2.50GHz | 24022a9 | 1787233149 | main |
| scenario | metric | min | mean ± sd | median ± mad | p75 | p95 | p99 | max | peak_to_median_ratio | skewness | kurtosis | cv | sem | runs | sample_size |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| sdk_test_data/rules-based | execution_time | 140.028µs | 143.702µs ± 5.713µs | 142.448µs ± 0.637µs | 143.286µs | 148.373µs | 167.353µs | 203.346µs | 42.75% | 7.393 | 65.500 | 3.97% | 0.404µs | 1 | 200 |
| scenario | metric | 95% CI mean | Shapiro-Wilk pvalue | Ljung-Box pvalue (lag=1) | Dip test pvalue |
|---|---|---|---|---|---|
| sdk_test_data/rules-based | execution_time | [142.910µs; 144.494µs] or [-0.551%; +0.551%] | None | None | None |
Artifact Size Benchmark Reportaarch64-alpine-linux-musl
aarch64-unknown-linux-gnu
libdatadog-x64-windows
libdatadog-x86-windows
x86_64-alpine-linux-musl
x86_64-unknown-linux-gnu
|
1b7d17e to
6a33037
Compare
Model the top-level UFC `observeFullEvaluationData` boolean through the wire -> compiled -> Configuration layers and add `ddog_ffe_configuration_get_observe_full_evaluation_data` so SDKs can read whether to emit full flag-evaluation data without re-parsing the raw JSON string. Defaults to `false` (privacy-preserving) when the field is absent from the server payload, so older configurations are a no-op. This is the libdatadog half of the "Protecting PII in flagevaluations track" initiative; the server-side UFC field already ships via ddoghq/dd-source#22826 and the RC schema via ddoghq/dd-go#3627. Refs: FFL-3038 Generated with Claude Code
b021c65 to
ea343ad
Compare
Address review findings on the observeFullEvaluationData accessor.
A `null` or mistyped value for this optional field previously failed the
parse of the whole configuration, which discarded every flag and forced
SDKs onto their defaults. Parse it leniently instead: any value that is
not a JSON boolean now falls back to `false`, the privacy-preserving
default. A malformed value can no longer take down unrelated flags.
`TryParse<bool>` was not usable here because `#[serde(default)]` needs
`Default`, which `TryParse` does not implement. Routing through
`serde_json::Value` also consumes nested shapes (`{}`, `[]`) cleanly,
which `Option::<bool>::deserialize` does not guarantee after a type
error.
The new FFI symbol had no assertion anywhere. The shared test fixture
omits the key, so `cargo ffi-test` only ever exercised the `false` path.
Add Rust tests that drive the real `ddog_ffe_configuration_new` ->
getter -> `ddog_ffe_configuration_drop` sequence for the true, false,
absent, and malformed cases, and make the C example assert the expected
default rather than only printing it.
Also re-wrap the three new doc comments to satisfy `cargo fmt --check`.
Refs: FFL-3038
Generated with Claude Code
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 5dd17bc9b7
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
lgtm, please address Codex review comments |
Generated with Claude Code
Summary
Adds the top-level UFC
observeFullEvaluationDataboolean end-to-end through libdatadog and exposes a config-level FFI getter so SDKs can read it without re-parsing the raw JSON string. This is the libdatadog half of the "Protecting PII in flagevaluations track" initiative; the server-side UFC field ships via ddoghq/dd-source#22826 and the RC schema via ddoghq/dd-go#3627.true: SDK emits unhashedtargeting_key+ full evaluation context (today's behavior).false(default): SDK emits a SHA-256 hex hash of the targeting key and omits the context.Default is
false(privacy-preserving). A fresh deploy is a no-op for customers until an SDK ships the read-side change and someone toggles the field on for an env.Changes
UniversalFlagConfigWire(libdd-ffe): new#[serde(default)] bool observe_full_evaluation_datafield, a sibling ofenvironmentat the UFC top level.#[serde(default)]keeps older configurations (without the key) parsing tofalse.CompiledFlagsConfig: carries the field through the wire -> compiled transform.Configuration::observe_full_evaluation_data(): Rust getter, mirroring the existingcreated_at()/environment()accessors.ddog_ffe_configuration_get_observe_full_evaluation_data(libdd-ffe-ffi): new#[no_mangle]C accessor returningbool. Thedatadog/ffe.hheader regenerates via cbindgen.examples/ffi/ffe.c: prints the flag afterddog_ffe_configuration_newto demonstrate usage.Test plan
cargo check -p libdd-ffe -p libdd-ffe-fficargo +nightly-2026-07-26 fmt --all -- --checkcargo +nightly-2026-07-26 clippy -p libdd-ffe -p libdd-ffe-ffi --all-targets -- -D warningscargo nextest run -p libdd-ffe -p libdd-ffe-ffi(incl. 4 new unit tests: field defaults to false when absent, parses true when present, exposed viaConfigurationtrue/false)cargo test -p libdd-ffe --doccargo ffi-test—ffeC example compiles, links against the regenerated header (new symbol present), and runs green against theffe-system-test-datafixture.Refs: FFL-3038