Skip to content

feat(ffe): expose prerequisite evaluations through C FFI - #2791

Open
hhan2024 wants to merge 1 commit into
helen/ffe-dependent-flags-evaluatorfrom
helen/dependent-flags-sdk-ffi
Open

hhan2024 wants to merge 1 commit into
helen/ffe-dependent-flags-evaluatorfrom
helen/dependent-flags-sdk-ffi

Conversation

@hhan2024

@hhan2024 hhan2024 commented Nov 3, 2026 •

Copy link
Copy Markdown
Contributor

Ruby calls the shared Rust feature-flag evaluator through its existing C extension and libdatadog's C FFI. The evaluator can now evaluate prerequisite flags, but the C FFI currently drops those prerequisite observations when converting the result into a resolution handle. Ruby therefore cannot report the prerequisite evaluations and eligible exposures associated with a dependent-flag assignment.

This PR carries those observations across the C FFI boundary so dd-trace-rb #6613 can consume them:

Ruby OpenFeature provider
  ↕ Ruby C extension                       dd-trace-rb #6613
  ↕ libdatadog C FFI prerequisite accessors this PR
  ↕ Shared Rust dependent-flag evaluator   libdatadog #2748

The accessors expose each reached prerequisite's flag key, evaluation result (including errors), and exposure eligibility. The Ruby integration uses these results to report prerequisite evaluation counts/metrics and eligible exposures, respecting the evaluator's decisions about which prerequisites contributed to the assignment. Each child result is independently owned and remains valid after the root result and configuration are freed.

This is an extension of the native bridge used by Ruby; it does not introduce a standalone C feature-flagging SDK. Dependent-flag evaluation logic lives in #2748. Ruby-side capability advertisement, result consumption, and telemetry are implemented in dd-trace-rb #6613.

Stacked on #2748; this diff contains only the FFI integration and its tests. Ruby's release dependency must be updated to a published libdatadog package containing both PRs before default installations can enable dependent-flag support.

Validation: 9 FFI unit tests and doc tests; cargo check, Clippy and formatting; AST checks (existing repository warnings); C FFI ownership example compiled and passed through cargo ffi-test --skip-build --filter ffe_dependencies. The Ruby consumer also passed 991 OpenFeature examples against a clean local native build of this stack.

Expose owned prerequisite results and exposure eligibility for server SDK integrations.

Environment: Datadog workspace

Co-Authored-By: Codex GPT-6 <noreply@localhost>
@github-actions

github-actions Bot commented Nov 3, 2026 •

Copy link
Copy Markdown
Contributor

📚 Documentation Check Results

⚠️ 525 documentation warning(s) found

📦 libdd-ffe-ffi - 525 warning(s)


Updated: 2026-11-04 17:11:25 UTC | Commit: 67927fc | missing-docs job results

@github-actions

github-actions Bot commented Nov 3, 2026 •

Copy link
Copy Markdown
Contributor

🔒 Cargo Deny Results

⚠️ 6 issue(s) found, showing only errors (advisories, bans, sources)

📦 libdd-ffe-ffi - 6 error(s)

Show output
info: syncing channel updates for 1.91.1-x86_64-unknown-linux-gnu
info: latest update on 2025-11-10 for version 1.91.1 (ed61e7d7e 2025-11-07)
info: downloading 6 components
warn: the missing active toolchain `1.91.1-x86_64-unknown-linux-gnu` has been auto-installed
warn: this might cause rustup commands to take longer time to finish than expected
info: you may opt out with `RUSTUP_AUTO_INSTALL=0` or `rustup set auto-install disable`
error[unmaintained]: Bincode is unmaintained
   ┌─ /home/runner/work/libdatadog/libdatadog/Cargo.lock:25:1
   │
25 │ bincode 1.3.3 registry+https://github.com/rust-lang/crates.io-index
   │ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ unmaintained advisory detected
   │
   ├ ID: RUSTSEC-2025-0141
   ├ Advisory: https://rustsec.org/advisories/RUSTSEC-2025-0141
   ├ Due to a doxxing and harassment incident, the bincode team has taken the decision to cease development permanently.
     
     The team considers version 1.3.3 a complete version of bincode that is not in need of any updates.
     
     ## Alternatives to consider
     
     * [wincode](https://crates.io/crates/wincode)
     * [postcard](https://crates.io/crates/postcard)
     * [bitcode](https://crates.io/crates/bitcode)
     * [rkyv](https://crates.io/crates/rkyv)
   ├ Announcement: https://git.sr.ht/~stygianentity/bincode/tree/v3.0/item/README.md
   ├ Solution: No safe upgrade is available!
   ├ bincode v1.3.3
     └── (dev) libdd-ffe v2.0.0
         └── libdd-ffe-ffi v1.0.2

error[vulnerability]: TLS 1.3 handshake messages incorrectly accepted across encryption level boundaries
    ┌─ /home/runner/work/libdatadog/libdatadog/Cargo.lock:197:1
    │
197 │ rustls 0.23.37 registry+https://github.com/rust-lang/crates.io-index
    │ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ security vulnerability detected
    │
    ├ ID: RUSTSEC-2026-0285
    ├ Advisory: https://rustsec.org/advisories/RUSTSEC-2026-0285
    ├ Rustls accepted TLS 1.3 handshake messages sent at the wrong encryption level
      when they followed a key-changing message in the same record. For example,
      a plaintext `EncryptedExtensions` message packed into the same record as the
      `ServerHello` was accepted.
      
      RFC 8446 section 5.1 requires that handshake messages do not span key changes,
      and that implementations terminate the connection with an "unexpected_message"
      alert if they do.
      
      The handshake transcript is still authenticated, so a network-position attacker
      cannot use this to alter or complete a handshake; the practical effect is that
      a peer could send handshake messages that should be encrypted in plaintext
      without rustls rejecting the connection.
      
      This is functionally the same bug as Go's
      [GO-2026-4340](https://pkg.go.dev/vuln/GO-2026-4340) (CVE-2025-61730).
    ├ Announcement: https://github.com/rustls/rustls/pull/3265
    ├ Solution: Upgrade to >=0.23.45 (try `cargo update -p rustls`)
    ├ rustls v0.23.37
      ├── hyper-rustls v0.27.7
      │   └── libdd-common v9.0.0
      │       ├── libdd-capabilities-impl v8.0.0
      │       │   ├── (dev) libdd-ffe v2.0.0
      │       │   │   └── libdd-ffe-ffi v1.0.2
      │       │   └── libdd-remote-config v8.0.0
      │       │       ├── libdd-ffe v2.0.0 (*)
      │       │       └── (dev) libdd-remote-config v8.0.0 (*)
      │       ├── libdd-common-ffi v47.0.0
      │       │   └── libdd-ffe-ffi v1.0.2 (*)
      │       ├── libdd-ffe v2.0.0 (*)
      │       └── libdd-remote-config v8.0.0 (*)
      ├── libdd-common v9.0.0 (*)
      ├── rustls-platform-verifier v0.6.2
      │   └── libdd-common v9.0.0 (*)
      └── tokio-rustls v0.26.0
          ├── hyper-rustls v0.27.7 (*)
          └── (dev) libdd-common v9.0.0 (*)

error[vulnerability]: `Debug` impls for client session values expose TLS secrets
    ┌─ /home/runner/work/libdatadog/libdatadog/Cargo.lock:197:1
    │
197 │ rustls 0.23.37 registry+https://github.com/rust-lang/crates.io-index
    │ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ security vulnerability detected
    │
    ├ ID: RUSTSEC-2026-0346
    ├ Advisory: https://rustsec.org/advisories/RUSTSEC-2026-0346
    ├ The `Debug` implementations of `Tls12ClientSessionValue` and
      `Tls13ClientSessionValue` were derived, and so included the TLS 1.2 master
      secret or TLS 1.3 resumption PSK in their output.
      
      Custom `ClientSessionStore` implementations that format these values with
      `Debug` (for example, when logging) could disclose these secrets to readers of
      the logs. This conflicts with rustls's
      [key-material redaction policy](https://github.com/rustls/rustls/blob/99f2358cae2954837dbb866faf6727de75489ab9/SECURITY.md#boundary-public-api).
      
      Ordinary connection and built-in session cache `Debug` output is redacted and
      is not affected.
    ├ Announcement: https://github.com/rustls/rustls/pull/3299
    ├ Solution: Upgrade to >=0.23.46 (try `cargo update -p rustls`)
    ├ rustls v0.23.37
      ├── hyper-rustls v0.27.7
      │   └── libdd-common v9.0.0
      │       ├── libdd-capabilities-impl v8.0.0
      │       │   ├── (dev) libdd-ffe v2.0.0
      │       │   │   └── libdd-ffe-ffi v1.0.2
      │       │   └── libdd-remote-config v8.0.0
      │       │       ├── libdd-ffe v2.0.0 (*)
      │       │       └── (dev) libdd-remote-config v8.0.0 (*)
      │       ├── libdd-common-ffi v47.0.0
      │       │   └── libdd-ffe-ffi v1.0.2 (*)
      │       ├── libdd-ffe v2.0.0 (*)
      │       └── libdd-remote-config v8.0.0 (*)
      ├── libdd-common v9.0.0 (*)
      ├── rustls-platform-verifier v0.6.2
      │   └── libdd-common v9.0.0 (*)
      └── tokio-rustls v0.26.0
          ├── hyper-rustls v0.27.7 (*)
          └── (dev) libdd-common v9.0.0 (*)

error[vulnerability]: Brotli certificate decompression can allocate up to 1 GiB before authentication
    ┌─ /home/runner/work/libdatadog/libdatadog/Cargo.lock:197:1
    │
197 │ rustls 0.23.37 registry+https://github.com/rust-lang/crates.io-index
    │ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ security vulnerability detected
    │
    ├ ID: RUSTSEC-2026-0348
    ├ Advisory: https://rustsec.org/advisories/RUSTSEC-2026-0348
    ├ The built-in Brotli certificate decompressor (enabled by the non-default
      `brotli` crate feature) bounded the size of the decompressed output, but
      accepted a peer-selected history window. Brotli's large-window extension was
      enabled, so a five-byte header could cause an allocation of 1 GiB. A peer can
      abort a process whose allocator cannot satisfy that request.
      
      No trusted certificate is required by the attacker. Affected configurations are:
      
      - clients that enable the `brotli` feature and connect to a malicious server, and
      - servers that enable the `brotli` feature and request client certificates.
      
      Applications that do not enable the `brotli` feature are not affected.
    ├ Announcement: https://github.com/rustls/rustls/pull/3297
    ├ Solution: Upgrade to >=0.23.46 (try `cargo update -p rustls`)
    ├ rustls v0.23.37
      ├── hyper-rustls v0.27.7
      │   └── libdd-common v9.0.0
      │       ├── libdd-capabilities-impl v8.0.0
      │       │   ├── (dev) libdd-ffe v2.0.0
      │       │   │   └── libdd-ffe-ffi v1.0.2
      │       │   └── libdd-remote-config v8.0.0
      │       │       ├── libdd-ffe v2.0.0 (*)
      │       │       └── (dev) libdd-remote-config v8.0.0 (*)
      │       ├── libdd-common-ffi v47.0.0
      │       │   └── libdd-ffe-ffi v1.0.2 (*)
      │       ├── libdd-ffe v2.0.0 (*)
      │       └── libdd-remote-config v8.0.0 (*)
      ├── libdd-common v9.0.0 (*)
      ├── rustls-platform-verifier v0.6.2
      │   └── libdd-common v9.0.0 (*)
      └── tokio-rustls v0.26.0
          ├── hyper-rustls v0.27.7 (*)
          └── (dev) libdd-common v9.0.0 (*)

error[vulnerability]: Unauthenticated ServerHello can downgrade later connections to classical key exchange
    ┌─ /home/runner/work/libdatadog/libdatadog/Cargo.lock:197:1
    │
197 │ rustls 0.23.37 registry+https://github.com/rust-lang/crates.io-index
    │ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ security vulnerability detected
    │
    ├ ID: RUSTSEC-2026-0349
    ├ Advisory: https://rustsec.org/advisories/RUSTSEC-2026-0349
    ├ The client recorded the server-selected key exchange group for each server
      name when processing the ServerHello, before the server was authenticated.
      This record is used to predict which key share to send in future ClientHellos
      to that server name.
      
      A network attacker can answer one connection attempt with a ServerHello
      selecting X25519, and then close the connection. Later ClientHellos for that
      name carry only an X25519 key share, while `supported_groups` still lists
      X25519MLKEM768 first. If the genuine server accepts that share rather than
      sending a HelloRetryRequest for its preferred hybrid group, the handshake
      completes with classical-only key exchange and no error. This persists for as
      long as the entry stays in the client's session store.
      
      The impact is loss of post-quantum confidentiality for affected connections
      ("harvest now, decrypt later"). There is no key compromise and no
      authentication bypass.
      
      The following are not affected:
      
      - connections to servers which send a HelloRetryRequest for their preferred group,
      - clients with resumption disabled (as nothing is stored), and
      - other server names.
      
      This behaviour is discussed in
      [draft-ietf-tls-key-share-prediction](https://www.ietf.org/archive/id/draft-ietf-tls-key-share-prediction-01.html#name-security-considerations),
      so the practical impact depends largely on server policy.
    ├ Announcement: https://github.com/rustls/rustls/pull/3355
    ├ Solution: Upgrade to >=0.23.46 (try `cargo update -p rustls`)
    ├ rustls v0.23.37
      ├── hyper-rustls v0.27.7
      │   └── libdd-common v9.0.0
      │       ├── libdd-capabilities-impl v8.0.0
      │       │   ├── (dev) libdd-ffe v2.0.0
      │       │   │   └── libdd-ffe-ffi v1.0.2
      │       │   └── libdd-remote-config v8.0.0
      │       │       ├── libdd-ffe v2.0.0 (*)
      │       │       └── (dev) libdd-remote-config v8.0.0 (*)
      │       ├── libdd-common-ffi v47.0.0
      │       │   └── libdd-ffe-ffi v1.0.2 (*)
      │       ├── libdd-ffe v2.0.0 (*)
      │       └── libdd-remote-config v8.0.0 (*)
      ├── libdd-common v9.0.0 (*)
      ├── rustls-platform-verifier v0.6.2
      │   └── libdd-common v9.0.0 (*)
      └── tokio-rustls v0.26.0
          ├── hyper-rustls v0.27.7 (*)
          └── (dev) libdd-common v9.0.0 (*)

error[unsound]: `AsyncFd::new` and related constructors violate I/O safety
    ┌─ /home/runner/work/libdatadog/libdatadog/Cargo.lock:248:1
    │
248 │ tokio 1.49.0 registry+https://github.com/rust-lang/crates.io-index
    │ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ unsound advisory detected
    │
    ├ ID: RUSTSEC-2026-0386
    ├ Advisory: https://rustsec.org/advisories/RUSTSEC-2026-0386
    ├ `tokio::io::unix::AsyncFd` provides safe constructors (`new`, `with_interest`, `try_new`, and `try_with_interest`) that accept any `T: AsRawFd` rather than requiring proof of ownership or validity of the file descriptor. Because `RawFd` implements `AsRawFd`, safe code can construct an `AsyncFd` from an arbitrary or closed file descriptor, or close/replace the underlying file descriptor while the `AsyncFd` is still alive.
      
      This violates I/O safety in two ways:
      
      1. `AsyncFd<T>` implements `AsFd` for all `T: AsRawFd` by calling `BorrowedFd::borrow_raw(self.as_raw_fd())`, allowing safe code to obtain an arbitrary `BorrowedFd<'_>` without owning the file descriptor.
      2. Tokio's I/O driver stores a pointer to an internal allocation in the `epoll`/`kqueue` user data for registered file descriptors. If the underlying file descriptor is duplicated and then closed while an `AsyncFd` is alive, and the OS reuses that file descriptor number for a another IO resource on the same runtime, dropping the first `AsyncFd` deregisters the reused file descriptor number and frees the first while the original file description remains registered in `epoll`, leading to a use-after-free when a readiness event fires.
      
      Starting in Tokio 1.51.6, 1.53.3, and 1.54.0, `AsyncFd::new`, `AsyncFd::with_interest`, `AsyncFd::try_new`, and `AsyncFd::try_with_interest` are deprecated in favor of the `unsafe` constructors `AsyncFd::register` and `AsyncFd::register_with_interest`. Callers must ensure that the file descriptor remains valid, open, and unchanged for the lifetime of the `AsyncFd`.
    ├ Announcement: https://github.com/tokio-rs/tokio/pull/8587
    ├ Solution: Upgrade to >=1.51.6, <1.52.0 OR >=1.53.3 (try `cargo update -p tokio`)
    ├ tokio v1.49.0
      ├── h2 v0.4.19
      │   └── hyper v1.11.1
      │       ├── httpmock v0.8.0-alpha.1
      │       │   └── (dev) libdd-ffe v2.0.0
      │       │       └── libdd-ffe-ffi v1.0.2
      │       ├── hyper-rustls v0.27.7
      │       │   └── libdd-common v9.0.0
      │       │       ├── libdd-capabilities-impl v8.0.0
      │       │       │   ├── (dev) libdd-ffe v2.0.0 (*)
      │       │       │   └── libdd-remote-config v8.0.0
      │       │       │       ├── libdd-ffe v2.0.0 (*)
      │       │       │       └── (dev) libdd-remote-config v8.0.0 (*)
      │       │       ├── libdd-common-ffi v47.0.0
      │       │       │   └── libdd-ffe-ffi v1.0.2 (*)
      │       │       ├── libdd-ffe v2.0.0 (*)
      │       │       └── libdd-remote-config v8.0.0 (*)
      │       ├── hyper-util v0.1.17
      │       │   ├── httpmock v0.8.0-alpha.1 (*)
      │       │   ├── hyper-rustls v0.27.7 (*)
      │       │   ├── libdd-common v9.0.0 (*)
      │       │   └── libdd-remote-config v8.0.0 (*)
      │       ├── libdd-common v9.0.0 (*)
      │       ├── libdd-common-ffi v47.0.0 (*)
      │       └── libdd-remote-config v8.0.0 (*)
      ├── httpmock v0.8.0-alpha.1 (*)
      ├── hyper v1.11.1 (*)
      ├── hyper-rustls v0.27.7 (*)
      ├── hyper-util v0.1.17 (*)
      ├── (dev) libdd-capabilities-impl v8.0.0 (*)
      ├── (dev) libdd-common v9.0.0 (*)
      ├── (dev) libdd-ffe v2.0.0 (*)
      ├── libdd-remote-config v8.0.0 (*)
      ├── (dev) libdd-trace-protobuf v5.1.1
      │   └── libdd-remote-config v8.0.0 (*)
      ├── tokio-rustls v0.26.0
      │   ├── hyper-rustls v0.27.7 (*)
      │   └── (dev) libdd-common v9.0.0 (*)
      ├── tokio-util v0.7.12
      │   ├── h2 v0.4.19 (*)
      │   └── libdd-remote-config v8.0.0 (*)
      └── (dev) tools v47.0.0
          └── (dev) libdd-common v9.0.0 (*)

advisories FAILED, bans ok, sources ok

Updated: 2026-11-04 17:10:55 UTC | Commit: 67927fc | dependency-check job results

@datadog-official

datadog-official Bot commented Nov 3, 2026 •

Copy link
Copy Markdown

Pipelines  Tests

🎉 All green!

🧪 All tests passed
❄️ No new flaky tests detected

🎯 Code Coverage (details)
• Patch Coverage: 83.81%
• Overall Coverage: 68.63% (-10.56%)

This comment will be updated automatically if new data arrives.
🔗 Commit SHA: a6cb21f | Docs | View more details | Give us feedback!

@pr-commenter

pr-commenter Bot commented Nov 3, 2026 •

Copy link
Copy Markdown

Benchmarks

Comparison

Benchmark execution time: 2026-11-03 01:44:13

Comparing candidate commit a6cb21f in PR branch helen/dependent-flags-sdk-ffi with baseline commit 1cf7834 in branch helen/ffe-dependent-flags-evaluator.

📊 Benchmarking dashboard

Found 0 performance improvements and 1 performance regressions! Performance is the same for 16 metrics, 0 unstable metrics.

Explanation

This is an A/B test comparing a candidate commit's performance against that of a baseline commit. Performance changes are noted in the tables below as:

  • 🟩 = significantly better candidate vs. baseline
  • 🟥 = significantly worse candidate vs. baseline

We compute a confidence interval (CI) over the relative difference of means between metrics from the candidate and baseline commits, considering the baseline as the reference.

If the CI is entirely outside the configured SIGNIFICANT_IMPACT_THRESHOLD (or the deprecated UNCONFIDENCE_THRESHOLD), the change is considered significant.

Feel free to reach out to #apm-benchmarking-platform on Slack if you have any questions.

More details about the CI and significant changes

You can imagine this CI as a range of values that is likely to contain the true difference of means between the candidate and baseline commits.

CIs of the difference of means are often centered around 0%, because often changes are not that big:

---------------------------------(------|---^--------)-------------------------------->
                              -0.6%    0%  0.3%     +1.2%
                                 |          |        |
         lower bound of the CI --'          |        |
sample mean (center of the CI) -------------'        |
         upper bound of the CI ----------------------'

As described above, a change is considered significant if the CI is entirely outside the configured SIGNIFICANT_IMPACT_THRESHOLD (or the deprecated UNCONFIDENCE_THRESHOLD).

For instance, for an execution time metric, this confidence interval indicates a significantly worse performance:

----------------------------------------|---------|---(---------^---------)---------->
                                       0%        1%  1.3%      2.2%      3.1%
                                                  |   |         |         |
       significant impact threshold --------------'   |         |         |
                      lower bound of CI --------------'         |         |
       sample mean (center of the CI) --------------------------'         |
                      upper bound of CI ----------------------------------'

scenario:dependent_flags/memoized_16_references

  • 🟥 execution_time [+307.679ns; +309.600ns] or [+10.216%; +10.280%]

Candidate

Candidate benchmark details

Group 1

cpu_model git_commit_sha git_commit_date git_branch
Intel(R) Xeon(R) Platinum 8259CL CPU @ 2.50GHz a6cb21f 1793669622 helen/dependent-flags-sdk-ffi
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 31.303ms 31.447ms ± 0.053ms 31.443ms ± 0.029ms 31.474ms 31.530ms 31.572ms 31.580ms 0.44% 0.047 0.622 0.17% 0.007ms 1 50
flagevaluation_evp/coalescer/scale/2500flags_500users_20fields throughput 79163.157op/s 79500.280op/s ± 133.183op/s 79508.193op/s ± 72.432op/s 79576.236op/s 79700.584op/s 79813.198op/s 79863.552op/s 0.45% -0.034 0.625 0.17% 18.835op/s 1 50
flagevaluation_evp/coalescer/stress/10flags_1000users_250fields execution_time 191.046ms 191.925ms ± 0.895ms 191.664ms ± 0.225ms 191.914ms 194.215ms 194.746ms 194.779ms 1.63% 2.479 5.251 0.46% 0.179ms 1 25
flagevaluation_evp/coalescer/stress/10flags_1000users_250fields throughput 5134.035op/s 5210.487op/s ± 24.036op/s 5217.465op/s ± 6.142op/s 5223.473op/s 5225.373op/s 5232.273op/s 5234.333op/s 0.32% -2.464 5.196 0.45% 4.807op/s 1 25
flagevaluation_evp/coalescer/typical/100flags_50users_10fields execution_time 686.033µs 696.655µs ± 4.014µs 696.590µs ± 1.939µs 699.620µs 703.532µs 704.311µs 704.359µs 1.12% -0.540 0.709 0.57% 0.401µs 1 100
flagevaluation_evp/coalescer/typical/100flags_50users_10fields throughput 141973.090op/s 143547.789op/s ± 829.859op/s 143556.415op/s ± 400.728op/s 143896.507op/s 145305.873op/s 145732.004op/s 145765.556op/s 1.54% 0.582 0.764 0.58% 82.986op/s 1 100
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 [31.432ms; 31.461ms] or [-0.046%; +0.046%] None None None
flagevaluation_evp/coalescer/scale/2500flags_500users_20fields throughput [79463.364op/s; 79537.196op/s] or [-0.046%; +0.046%] None None None
flagevaluation_evp/coalescer/stress/10flags_1000users_250fields execution_time [191.574ms; 192.276ms] or [-0.183%; +0.183%] None None None
flagevaluation_evp/coalescer/stress/10flags_1000users_250fields throughput [5201.065op/s; 5219.909op/s] or [-0.181%; +0.181%] None None None
flagevaluation_evp/coalescer/typical/100flags_50users_10fields execution_time [695.868µs; 697.442µs] or [-0.113%; +0.113%] None None None
flagevaluation_evp/coalescer/typical/100flags_50users_10fields throughput [143385.140op/s; 143710.439op/s] or [-0.113%; +0.113%] None None None

Group 2

cpu_model git_commit_sha git_commit_date git_branch
Intel(R) Xeon(R) Platinum 8259CL CPU @ 2.50GHz a6cb21f 1793669622 helen/dependent-flags-sdk-ffi
scenario metric min mean ± sd median ± mad p75 p95 p99 max peak_to_median_ratio skewness kurtosis cv sem runs sample_size
dependent_flags/one_prerequisite execution_time 727.818ns 731.538ns ± 1.198ns 731.370ns ± 0.290ns 731.729ns 732.667ns 737.619ns 740.429ns 1.24% 4.623 30.967 0.16% 0.085ns 1 200
scenario metric 95% CI mean Shapiro-Wilk pvalue Ljung-Box pvalue (lag=1) Dip test pvalue
dependent_flags/one_prerequisite execution_time [731.372ns; 731.704ns] or [-0.023%; +0.023%] None None None

Group 3

cpu_model git_commit_sha git_commit_date git_branch
Intel(R) Xeon(R) Platinum 8259CL CPU @ 2.50GHz a6cb21f 1793669622 helen/dependent-flags-sdk-ffi
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 199.370ns 202.372ns ± 1.885ns 202.055ns ± 1.541ns 203.773ns 206.132ns 207.101ns 208.658ns 3.27% 0.482 0.107 0.93% 0.133ns 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 [202.111ns; 202.634ns] or [-0.129%; +0.129%] None None None

Group 4

cpu_model git_commit_sha git_commit_date git_branch
Intel(R) Xeon(R) Platinum 8259CL CPU @ 2.50GHz a6cb21f 1793669622 helen/dependent-flags-sdk-ffi
scenario metric min mean ± sd median ± mad p75 p95 p99 max peak_to_median_ratio skewness kurtosis cv sem runs sample_size
dependent_flags/memoized_16_references execution_time 3.306µs 3.320µs ± 0.004µs 3.320µs ± 0.001µs 3.321µs 3.328µs 3.338µs 3.344µs 0.74% 1.995 9.073 0.13% 0.000µs 1 200
scenario metric 95% CI mean Shapiro-Wilk pvalue Ljung-Box pvalue (lag=1) Dip test pvalue
dependent_flags/memoized_16_references execution_time [3.320µs; 3.321µs] or [-0.018%; +0.018%] None None None

Group 5

cpu_model git_commit_sha git_commit_date git_branch
Intel(R) Xeon(R) Platinum 8259CL CPU @ 2.50GHz a6cb21f 1793669622 helen/dependent-flags-sdk-ffi
scenario metric min mean ± sd median ± mad p75 p95 p99 max peak_to_median_ratio skewness kurtosis cv sem runs sample_size
dependent_flags/legacy execution_time 113.202ns 113.896ns ± 0.116ns 113.897ns ± 0.048ns 113.943ns 114.037ns 114.152ns 114.539ns 0.56% -0.563 12.948 0.10% 0.008ns 1 200
scenario metric 95% CI mean Shapiro-Wilk pvalue Ljung-Box pvalue (lag=1) Dip test pvalue
dependent_flags/legacy execution_time [113.880ns; 113.912ns] or [-0.014%; +0.014%] None None None

Group 6

cpu_model git_commit_sha git_commit_date git_branch
Intel(R) Xeon(R) Platinum 8259CL CPU @ 2.50GHz a6cb21f 1793669622 helen/dependent-flags-sdk-ffi
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 301.624µs 306.945µs ± 12.094µs 304.074µs ± 1.291µs 305.729µs 320.962µs 355.625µs 429.028µs 41.09% 6.836 57.467 3.93% 0.855µ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 [305.269µs; 308.622µs] or [-0.546%; +0.546%] None None None

Group 7

cpu_model git_commit_sha git_commit_date git_branch
Intel(R) Xeon(R) Platinum 8259CL CPU @ 2.50GHz a6cb21f 1793669622 helen/dependent-flags-sdk-ffi
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 34.233ms 34.415ms ± 0.086ms 34.421ms ± 0.053ms 34.459ms 34.565ms 34.609ms 34.633ms 0.62% 0.165 -0.058 0.25% 0.012ms 1 50
flagevaluation_evp/payloads/scale/2500flags_500users_20fields throughput 72185.742op/s 72643.745op/s ± 182.297op/s 72630.621op/s ± 111.628op/s 72762.290op/s 72930.973op/s 73011.807op/s 73029.429op/s 0.55% -0.151 -0.068 0.25% 25.781op/s 1 50
flagevaluation_evp/payloads/stress/10flags_1000users_250fields execution_time 184.437ms 185.013ms ± 0.312ms 185.063ms ± 0.198ms 185.210ms 185.411ms 185.559ms 185.603ms 0.29% -0.265 -0.715 0.17% 0.062ms 1 25
flagevaluation_evp/payloads/stress/10flags_1000users_250fields throughput 5387.832op/s 5405.054op/s ± 9.120op/s 5403.576op/s ± 5.794op/s 5411.655op/s 5420.944op/s 5421.781op/s 5421.901op/s 0.34% 0.271 -0.715 0.17% 1.824op/s 1 25
flagevaluation_evp/payloads/typical/100flags_50users_10fields execution_time 846.236µs 848.580µs ± 0.790µs 848.566µs ± 0.549µs 849.143µs 849.751µs 850.195µs 850.533µs 0.23% -0.078 -0.112 0.09% 0.079µs 1 100
flagevaluation_evp/payloads/typical/100flags_50users_10fields throughput 117573.276op/s 117844.024op/s ± 109.674op/s 117845.860op/s ± 76.182op/s 117914.504op/s 118024.995op/s 118072.083op/s 118170.362op/s 0.28% 0.084 -0.108 0.09% 10.967op/s 1 100
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 [34.391ms; 34.439ms] or [-0.070%; +0.070%] None None None
flagevaluation_evp/payloads/scale/2500flags_500users_20fields throughput [72593.215op/s; 72694.274op/s] or [-0.070%; +0.070%] None None None
flagevaluation_evp/payloads/stress/10flags_1000users_250fields execution_time [184.890ms; 185.135ms] or [-0.066%; +0.066%] None None None
flagevaluation_evp/payloads/stress/10flags_1000users_250fields throughput [5401.480op/s; 5408.629op/s] or [-0.066%; +0.066%] None None None
flagevaluation_evp/payloads/typical/100flags_50users_10fields execution_time [848.425µs; 848.735µs] or [-0.018%; +0.018%] None None None
flagevaluation_evp/payloads/typical/100flags_50users_10fields throughput [117822.528op/s; 117865.519op/s] or [-0.018%; +0.018%] 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 1cf7834 1793629234 helen/ffe-dependent-flags-evaluator
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 31.222ms 31.356ms ± 0.047ms 31.360ms ± 0.030ms 31.386ms 31.417ms 31.445ms 31.448ms 0.28% -0.615 0.342 0.15% 0.007ms 1 50
flagevaluation_evp/coalescer/scale/2500flags_500users_20fields throughput 79497.190op/s 79729.404op/s ± 119.601op/s 79720.283op/s ± 75.564op/s 79809.378op/s 79945.131op/s 80030.213op/s 80071.549op/s 0.44% 0.623 0.355 0.15% 16.914op/s 1 50
flagevaluation_evp/coalescer/stress/10flags_1000users_250fields execution_time 190.785ms 191.513ms ± 1.011ms 191.243ms ± 0.123ms 191.383ms 194.147ms 194.833ms 194.842ms 1.88% 2.937 7.015 0.52% 0.202ms 1 25
flagevaluation_evp/coalescer/stress/10flags_1000users_250fields throughput 5132.367op/s 5221.716op/s ± 27.157op/s 5228.941op/s ± 3.354op/s 5232.014op/s 5238.443op/s 5241.026op/s 5241.493op/s 0.24% -2.931 6.993 0.51% 5.431op/s 1 25
flagevaluation_evp/coalescer/typical/100flags_50users_10fields execution_time 685.136µs 697.928µs ± 4.330µs 699.408µs ± 2.478µs 700.774µs 702.946µs 703.750µs 703.766µs 0.62% -1.115 0.601 0.62% 0.433µs 1 100
flagevaluation_evp/coalescer/typical/100flags_50users_10fields throughput 142092.602op/s 143286.687op/s ± 895.127op/s 142978.128op/s ± 506.665op/s 143763.878op/s 145381.118op/s 145477.230op/s 145956.423op/s 2.08% 1.140 0.665 0.62% 89.513op/s 1 100
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 [31.343ms; 31.369ms] or [-0.042%; +0.042%] None None None
flagevaluation_evp/coalescer/scale/2500flags_500users_20fields throughput [79696.253op/s; 79762.555op/s] or [-0.042%; +0.042%] None None None
flagevaluation_evp/coalescer/stress/10flags_1000users_250fields execution_time [191.117ms; 191.909ms] or [-0.207%; +0.207%] None None None
flagevaluation_evp/coalescer/stress/10flags_1000users_250fields throughput [5211.071op/s; 5232.361op/s] or [-0.204%; +0.204%] None None None
flagevaluation_evp/coalescer/typical/100flags_50users_10fields execution_time [697.080µs; 698.777µs] or [-0.122%; +0.122%] None None None
flagevaluation_evp/coalescer/typical/100flags_50users_10fields throughput [143111.245op/s; 143462.128op/s] or [-0.122%; +0.122%] None None None

Group 2

cpu_model git_commit_sha git_commit_date git_branch
Intel(R) Xeon(R) Platinum 8259CL CPU @ 2.50GHz 1cf7834 1793629234 helen/ffe-dependent-flags-evaluator
scenario metric min mean ± sd median ± mad p75 p95 p99 max peak_to_median_ratio skewness kurtosis cv sem runs sample_size
dependent_flags/one_prerequisite execution_time 718.396ns 722.385ns ± 1.011ns 722.296ns ± 0.274ns 722.575ns 723.418ns 726.757ns 731.304ns 1.25% 3.927 34.205 0.14% 0.071ns 1 200
scenario metric 95% CI mean Shapiro-Wilk pvalue Ljung-Box pvalue (lag=1) Dip test pvalue
dependent_flags/one_prerequisite execution_time [722.245ns; 722.525ns] or [-0.019%; +0.019%] None None None

Group 3

cpu_model git_commit_sha git_commit_date git_branch
Intel(R) Xeon(R) Platinum 8259CL CPU @ 2.50GHz 1cf7834 1793629234 helen/ffe-dependent-flags-evaluator
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 199.889ns 203.039ns ± 1.929ns 202.689ns ± 1.411ns 204.435ns 206.582ns 207.611ns 208.777ns 3.00% 0.373 -0.257 0.95% 0.136ns 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 [202.772ns; 203.307ns] or [-0.132%; +0.132%] None None None

Group 4

cpu_model git_commit_sha git_commit_date git_branch
Intel(R) Xeon(R) Platinum 8259CL CPU @ 2.50GHz 1cf7834 1793629234 helen/ffe-dependent-flags-evaluator
scenario metric min mean ± sd median ± mad p75 p95 p99 max peak_to_median_ratio skewness kurtosis cv sem runs sample_size
dependent_flags/memoized_16_references execution_time 2.997µs 3.012µs ± 0.005µs 3.011µs ± 0.001µs 3.013µs 3.015µs 3.027µs 3.065µs 1.79% 6.588 57.641 0.18% 0.000µs 1 200
scenario metric 95% CI mean Shapiro-Wilk pvalue Ljung-Box pvalue (lag=1) Dip test pvalue
dependent_flags/memoized_16_references execution_time [3.011µs; 3.013µs] or [-0.025%; +0.025%] None None None

Group 5

cpu_model git_commit_sha git_commit_date git_branch
Intel(R) Xeon(R) Platinum 8259CL CPU @ 2.50GHz 1cf7834 1793629234 helen/ffe-dependent-flags-evaluator
scenario metric min mean ± sd median ± mad p75 p95 p99 max peak_to_median_ratio skewness kurtosis cv sem runs sample_size
dependent_flags/legacy execution_time 110.380ns 110.935ns ± 0.128ns 110.930ns ± 0.042ns 110.970ns 111.085ns 111.334ns 111.689ns 0.68% 1.420 12.868 0.11% 0.009ns 1 200
scenario metric 95% CI mean Shapiro-Wilk pvalue Ljung-Box pvalue (lag=1) Dip test pvalue
dependent_flags/legacy execution_time [110.917ns; 110.953ns] or [-0.016%; +0.016%] None None None

Group 6

cpu_model git_commit_sha git_commit_date git_branch
Intel(R) Xeon(R) Platinum 8259CL CPU @ 2.50GHz 1cf7834 1793629234 helen/ffe-dependent-flags-evaluator
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 301.576µs 306.855µs ± 11.645µs 303.913µs ± 1.116µs 305.545µs 318.728µs 354.609µs 421.679µs 38.75% 6.709 54.626 3.79% 0.823µ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 [305.241µs; 308.469µs] or [-0.526%; +0.526%] None None None

Group 7

cpu_model git_commit_sha git_commit_date git_branch
Intel(R) Xeon(R) Platinum 8259CL CPU @ 2.50GHz 1cf7834 1793629234 helen/ffe-dependent-flags-evaluator
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 34.384ms 34.597ms ± 0.102ms 34.608ms ± 0.069ms 34.664ms 34.727ms 34.819ms 34.850ms 0.70% -0.060 -0.302 0.29% 0.014ms 1 50
flagevaluation_evp/payloads/scale/2500flags_500users_20fields throughput 71735.993op/s 72262.225op/s ± 213.305op/s 72236.807op/s ± 144.222op/s 72405.895op/s 72616.431op/s 72686.985op/s 72707.868op/s 0.65% 0.075 -0.310 0.29% 30.166op/s 1 50
flagevaluation_evp/payloads/stress/10flags_1000users_250fields execution_time 181.901ms 182.497ms ± 0.373ms 182.522ms ± 0.214ms 182.672ms 183.122ms 183.384ms 183.454ms 0.51% 0.500 0.301 0.20% 0.075ms 1 25
flagevaluation_evp/payloads/stress/10flags_1000users_250fields throughput 5450.959op/s 5479.549op/s ± 11.201op/s 5478.795op/s ± 6.425op/s 5487.757op/s 5496.780op/s 5497.358op/s 5497.482op/s 0.34% -0.488 0.281 0.20% 2.240op/s 1 25
flagevaluation_evp/payloads/typical/100flags_50users_10fields execution_time 836.113µs 837.936µs ± 0.889µs 837.877µs ± 0.588µs 838.490µs 839.435µs 840.087µs 840.474µs 0.31% 0.425 0.043 0.11% 0.089µs 1 100
flagevaluation_evp/payloads/typical/100flags_50users_10fields throughput 118980.510op/s 119340.948op/s ± 126.519op/s 119349.266op/s ± 83.787op/s 119424.125op/s 119542.600op/s 119576.452op/s 119601.053op/s 0.21% -0.419 0.036 0.11% 12.652op/s 1 100
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 [34.568ms; 34.625ms] or [-0.082%; +0.082%] None None None
flagevaluation_evp/payloads/scale/2500flags_500users_20fields throughput [72203.101op/s; 72321.349op/s] or [-0.082%; +0.082%] None None None
flagevaluation_evp/payloads/stress/10flags_1000users_250fields execution_time [182.351ms; 182.644ms] or [-0.080%; +0.080%] None None None
flagevaluation_evp/payloads/stress/10flags_1000users_250fields throughput [5475.159op/s; 5483.940op/s] or [-0.080%; +0.080%] None None None
flagevaluation_evp/payloads/typical/100flags_50users_10fields execution_time [837.762µs; 838.110µs] or [-0.021%; +0.021%] None None None
flagevaluation_evp/payloads/typical/100flags_50users_10fields throughput [119316.151op/s; 119365.745op/s] or [-0.021%; +0.021%] None None None

@dd-octo-sts

dd-octo-sts Bot commented Nov 3, 2026

Copy link
Copy Markdown
Contributor

Artifact Size Benchmark Report

aarch64-alpine-linux-musl
Artifact Baseline Commit Change
/aarch64-alpine-linux-musl/lib/libdatadog_profiling.so 9.21 MB 9.21 MB 0% (0 B) 👌
/aarch64-alpine-linux-musl/lib/libdatadog_profiling.a 95.99 MB 96.30 MB +.32% (+318.96 KB) 🔍
aarch64-unknown-linux-gnu
Artifact Baseline Commit Change
/aarch64-unknown-linux-gnu/lib/libdatadog_profiling.so 12.37 MB 12.38 MB +.07% (+9.75 KB) 🔍
/aarch64-unknown-linux-gnu/lib/libdatadog_profiling.a 107.14 MB 107.45 MB +.29% (+321.75 KB) 🔍
libdatadog-x64-windows
Artifact Baseline Commit Change
/libdatadog-x64-windows/debug/dynamic/datadog_profiling_ffi.dll 29.49 MB 29.57 MB +.27% (+83.00 KB) 🔍
/libdatadog-x64-windows/debug/dynamic/datadog_profiling_ffi.lib 99.67 KB 100.97 KB +1.30% (+1.30 KB) ⚠️
/libdatadog-x64-windows/debug/dynamic/datadog_profiling_ffi.pdb 191.42 MB 192.15 MB +.37% (+744.00 KB) 🔍
/libdatadog-x64-windows/debug/static/datadog_profiling_ffi.lib 795.51 MB 799.09 MB +.44% (+3.57 MB) 🔍
/libdatadog-x64-windows/release/dynamic/datadog_profiling_ffi.dll 9.71 MB 9.73 MB +.29% (+29.00 KB) 🔍
/libdatadog-x64-windows/release/dynamic/datadog_profiling_ffi.lib 99.67 KB 100.97 KB +1.30% (+1.30 KB) ⚠️
/libdatadog-x64-windows/release/dynamic/datadog_profiling_ffi.pdb 27.66 MB 27.76 MB +.33% (+96.00 KB) 🔍
/libdatadog-x64-windows/release/static/datadog_profiling_ffi.lib 55.67 MB 55.85 MB +.31% (+180.97 KB) 🔍
libdatadog-x86-windows
Artifact Baseline Commit Change
/libdatadog-x86-windows/debug/dynamic/datadog_profiling_ffi.dll 26.00 MB 26.07 MB +.30% (+80.00 KB) 🔍
/libdatadog-x86-windows/debug/dynamic/datadog_profiling_ffi.lib 101.22 KB 102.54 KB +1.30% (+1.32 KB) ⚠️
/libdatadog-x86-windows/debug/dynamic/datadog_profiling_ffi.pdb 197.14 MB 197.93 MB +.40% (+808.00 KB) 🔍
/libdatadog-x86-windows/debug/static/datadog_profiling_ffi.lib 782.41 MB 785.80 MB +.43% (+3.39 MB) 🔍
/libdatadog-x86-windows/release/dynamic/datadog_profiling_ffi.dll 7.49 MB 7.52 MB +.39% (+30.00 KB) 🔍
/libdatadog-x86-windows/release/dynamic/datadog_profiling_ffi.lib 101.22 KB 102.54 KB +1.30% (+1.32 KB) ⚠️
/libdatadog-x86-windows/release/dynamic/datadog_profiling_ffi.pdb 29.76 MB 29.86 MB +.34% (+104.00 KB) 🔍
/libdatadog-x86-windows/release/static/datadog_profiling_ffi.lib 52.58 MB 52.76 MB +.33% (+179.28 KB) 🔍
x86_64-alpine-linux-musl
Artifact Baseline Commit Change
/x86_64-alpine-linux-musl/lib/libdatadog_profiling.a 86.45 MB 86.75 MB +.35% (+312.80 KB) 🔍
/x86_64-alpine-linux-musl/lib/libdatadog_profiling.so 10.00 MB 10.02 MB +.27% (+28.00 KB) 🔍
x86_64-unknown-linux-gnu
Artifact Baseline Commit Change
/x86_64-unknown-linux-gnu/lib/libdatadog_profiling.a 102.17 MB 102.48 MB +.30% (+315.19 KB) 🔍
/x86_64-unknown-linux-gnu/lib/libdatadog_profiling.so 12.24 MB 12.28 MB +.30% (+38.84 KB) 🔍

@hhan2024
hhan2024 marked this pull request as ready for review November 4, 2026 03:49
@hhan2024
hhan2024 requested review from a team as code owners November 4, 2026 03:49
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Nov 4, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-11-04T03:53:36.580213Z a6cb21f Draft marked ready
🔒 Security Review ✅ Completed 2026-11-04T03:53:27.419764Z a6cb21f Draft marked ready
ℹ️ 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" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a6cb21f762

ℹ️ 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".

};

let assignment_result = config.eval_flag_with_options(
let evaluation = config.eval_flag_with_trace(

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve evaluation trace logging

When any ddog_ffe_get_assignment* entry point is used with trace logging enabled, this direct call to eval_flag_with_trace bypasses Configuration::eval_flag_with_options, whose success and failure branches emit the evaluator's log::trace! records. Consequently, all C FFI evaluations silently lose their existing diagnostic logs, including evaluations without prerequisites; retain equivalent logging while collecting the trace.

Useful? React with 👍 / 👎.

@aarsilv aarsilv added the crucible: reviewing A Crucible review has started; this PR has reviewer attention. label Nov 4, 2026
/// `assignment` must be a live handle.
#[unsafe(no_mangle)]
// allow(ffi-panic-boundary): reads the length of an owned vector.
pub unsafe extern "C" fn ddog_ffe_assignment_dependency_count(

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 Comment from Claude working with Aaron Silverman:

Heads up: This PR is based on 1cf7834, not on the current head of #2748 (983b4b0).

  • A merge of this head with 983b4b0 is clean, and 983b4b0 does not change any type that this PR uses.
  • 983b4b0 does change behavior that these accessors expose: prerequisites rejected by the depth guard now appear in ddog_ffe_assignment_dependency_count, an invalid maxDependencyDepth no longer fails ddog_ffe_configuration_new, and empty value lists are accepted.
  • This PR also conflicts with main in this file: main adds features and feature_destinations next to the new dependencies field. Keep all three fields.
  • The description reports 991 Ruby OpenFeature examples against a local build of this stack. Please rerun them after the rebase.

/// # Safety
/// `assignment` must be a live handle.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn ddog_ffe_assignment_dependency_result(

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 Comment from Claude working with Aaron Silverman:

[P3] Small API points to settle before these accessors ship.

  • This function returns an owned handle, but it has no #[must_use]. A caller that ignores the result leaks it. With #[must_use], cbindgen emits DDOG_CHECK_RETURN.
  • The new names (ddog_ffe_assignment_dependency_{count,key,exposure_eligible,result}) do not follow the existing ddog_ffe_assignment_get_* pattern. Consider ddog_ffe_assignment_get_dependency_*, before callers depend on them.
  • The allow(ffi-panic-boundary) comments say these calls only read an owned vector. Handle::as_ref can panic on a null handle, as the existing accessors can; these accessors require a live handle. Please reword the comments to say so.
  • The open Codex thread on line 298 is valid: calling eval_flag_with_trace directly bypasses the evaluator's log::trace! records for every C FFI evaluation. The impact is low (trace level only). The fix belongs in eval_flag_with_trace in feat(ffe): evaluate dependent flags with prerequisite telemetry #2748.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

crucible: reviewing A Crucible review has started; this PR has reviewer attention.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants