Skip to content

Add baseline Dynamic Tests for CNM - #54938

Draft
AlexandreYang wants to merge 55 commits into
mainfrom
alex/baseline_dynamic_test_for_cnm
Draft

Add baseline Dynamic Tests for CNM#54938
AlexandreYang wants to merge 55 commits into
mainfrom
alex/baseline_dynamic_test_for_cnm

Conversation

@AlexandreYang

@AlexandreYang AlexandreYang commented Aug 15, 2026

Copy link
Copy Markdown
Member

What does this PR do?

Adds opt-in baseline Dynamic Tests for Cloud Network Monitoring (CNM). Baseline mode selects a small, representative set of paths directly from each CNM connection snapshot when full connection-monitoring Dynamic Tests are disabled.

Traceroute must also be enabled in the system-probe configuration. If full connection-monitoring Dynamic Tests are enabled, they take precedence and the collector continues to use standard scheduling.

Motivation

Hosts without full Dynamic Tests currently have no included Network Path coverage for observed CNM traffic. Baseline mode provides limited recurring path visibility.

The selector favors connections that are more useful for diagnosis while keeping resource use predictable: timeout, RTO, and retransmit observations rank ahead of healthy traffic, then higher-volume connections rank first.

Design and key changes

Snapshot selection

  • Reuses the existing connection eligibility filters before ranking.
  • Selects at most three unique paths from each complete CNM snapshot.
  • Ranks diagnostic observations first, then total sent and received bytes, with the stable path hash as the final tie-breaker.
  • Keeps only the best three candidates while scanning, so selection memory remains bounded and connections are not aggregated.
  • Reconsiders a repeated path only when its later observation has a stronger score.

Data boundary

Both CNM producers populate the same generic ConnectionSignals structure on NetworkPathConnection: normalized timeout count, RTO count, retransmits, sent bytes, and received bytes. These are raw connection observations rather than baseline-specific derived state.

The baseline selector in baseline.go is the only layer that interprets those signals into the diagnostic and traffic-volume ranking dimensions. This keeps producer behavior equivalent without coupling the shared connection model to baseline policy.

Scheduling and payloads

Standard, baseline, and NetFlow paths share the collector's existing eligibility checks, path construction, scheduling telemetry, deduplication, interval, TTL, context limit, and rate limit. Baseline mode adds only the snapshot-ranking step before selected paths enter that common machinery.

Baseline results are recurring Dynamic Tests and carry dynamic_test_profile: "baseline" in Network Path payloads so downstream consumers can distinguish them from standard tests. Baseline-only operation also enables the collector and its reverse-DNS dependency.

Baseline mode and Dynamic Remote Configuration filters are compatible and independent: baseline mode controls snapshot ranking, while the effective local-plus-RC filter controls path admission. When an RC rule admits the winning baseline candidate, its configuration ID, source, and tags are preserved alongside dynamic_test_profile: "baseline".

E2E coverage

Adds a packaged-Agent E2E suite that generates CNM host traffic and verifies through fakeintake that a Network Path event is emitted with the baseline profile.

The existing Remote Config host-traffic suite and the new baseline suite now share one fixture. The fixture replaces the GHCR-backed HTTP container and runtime curl installation with Python standard-library HTTP and traffic generation, including readiness checks, cleanup, and failure logs.

Manual validation

Use this minimal datadog.yaml configuration:

network_config:
  enabled: true

network_path:
  connections_monitoring:
    baseline_tests_enabled: true

Enable traceroute in system-probe.yaml:

traceroute:
  enabled: true

After generating outbound TCP traffic from the host, verify that Network Path events are emitted with test_run_type: "dynamic" and dynamic_test_profile: "baseline". Up to three unique eligible paths should be selected from each CNM snapshot, subject to the existing collector filters and scheduling limits.

Describe how you validated your changes

  • bazel test //comp/networkpath/npcollector/impl:impl_test
  • Added focused unit coverage for selection order, each diagnostic signal, sent/received byte derivation, repeated-path handling, configuration, producer signal mapping, payload serialization, and recurring scheduling cadence.
  • Added packaged-Agent E2E coverage for baseline Network Path events through fakeintake.

Additional Notes

The new configuration setting defaults to false and remains an internal rollout control omitted from generated datadog.yaml examples.

@github-actions

Copy link
Copy Markdown
Contributor

@codex review

@dd-octo-sts dd-octo-sts Bot added the internal Identify a non-fork PR label Aug 15, 2026
@github-actions github-actions Bot added the short review PR is simple enough to be reviewed quickly label Aug 15, 2026
@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Breezy!

Reviewed commit: 778ceec894

ℹ️ About Codex in GitHub

Codex has been enabled to automatically 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 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

@dd-octo-sts

dd-octo-sts Bot commented Aug 15, 2026

Copy link
Copy Markdown
Contributor

Files inventory check summary

File checks results against ancestor a614467d:

Results for datadog-agent_7.84.0~devel.git.272.3f6a287.pipeline.131208369-1_amd64.deb:

No change detected

Results for datadog-iot-agent_7.84.0~devel.git.272.3f6a287.pipeline.131208369-1_amd64.deb:

No change detected

@AlexandreYang

Copy link
Copy Markdown
Member Author

@codex make a comprehensive code and security review

Classify findings as P0 (critical), P1 (high), P2 (substantive), or P3 (optional). Include the priority, file, line, failure scenario, impact, and whether the finding is in scope for this PR.

Focus especially on keeping the implementation minimal and feature-scoped, preserving existing behavior when baseline_tests.enabled is false, bounded-memory selection, one-shot/window semantics, and test evidence.

@AlexandreYang
AlexandreYang requested a lite review from Copilot August 15, 2026 18:43
@github-actions github-actions Bot removed the short review PR is simple enough to be reviewed quickly label Aug 15, 2026
@github-actions github-actions Bot added the long review PR is complex, plan time to review it label Aug 15, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Introduces an opt-in “baseline” mode for Cloud Network Monitoring (CNM) Dynamic Tests, enabling a small bounded set of one-shot path tests while keeping recurring Dynamic Tests disabled by default.

Changes:

  • Add config/schema/docs/release notes for network_path.connections_monitoring.baseline_tests.enabled.
  • Resolve effective Dynamic Tests state (off/baseline/standard) and wire it into system-probe module enabling and the network path collector scheduling logic.
  • Add baseline candidate signal extraction + bounded baseline selector, plus payload metadata (dynamic_test_profile) and related metrics/tests.

Reviewed changes

Copilot reviewed 36 out of 36 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
releasenotes/notes/add-cnm-baseline-dynamic-tests-ac7c4a3d73c865b4.yaml Release note announcing baseline CNM Dynamic Tests behavior and config knob.
pkg/system-probe/config/config_test.go Adds tests asserting Traceroute module enablement under baseline/standard dynamic test states.
pkg/system-probe/config/config.go Enables Traceroute module based on resolved dynamic tests state and publishes derived sysprobe enablement.
pkg/system-probe/config/BUILD.bazel Adds dependency on pkg/networkpath/config for state resolution.
pkg/process/checks/net.go Populates baseline-ranking signals onto network path connections produced by process-agent.
pkg/networkpath/payload/payload_test.go Adds serialization test for the new dynamic_test_profile JSON field.
pkg/networkpath/payload/pathevent.go Introduces DynamicTestProfile and adds dynamic_test_profile to payload.
pkg/networkpath/payload/BUILD.bazel Adds testify/assert dependency for new payload test.
pkg/networkpath/config/state_test.go Adds unit tests for dynamic tests state resolution.
pkg/networkpath/config/state.go New resolver combining core + sysprobe flags into an effective dynamic tests state.
pkg/networkpath/config/BUILD.bazel Bazel targets for the new networkpath config package and tests.
pkg/network/sender/sender_linux.go Populates baseline-ranking signals onto network path connections produced by system-probe sender.
pkg/config/setup/config_test.go Ensures baseline flag default is false.
pkg/config/schema/yaml/core_schema.yaml Adds schema for baseline_tests.enabled under connections monitoring.
pkg/config/example/datadog-agent_windows.yaml.example Documents baseline tests config option in Windows example config.
pkg/config/example/datadog-agent_linux.yaml.example Documents baseline tests config option in Linux example config.
comp/networkpath/npcollector/model/connection_test.go Tests new baseline signal normalization and saturation behavior.
comp/networkpath/npcollector/model/connection.go Adds baseline signal fields, saturation logic, and a shared SetBaselineSignals helper.
comp/networkpath/npcollector/model/BUILD.bazel Adds go_test rule for the new model unit test.
comp/networkpath/npcollector/impl/pathteststore/pathteststore_test.go Adds tests for one-shot dispatch/deletion and deadline expiry metrics.
comp/networkpath/npcollector/impl/pathteststore/pathteststore.go Adds one-shot execution deadline handling, baseline metrics, and dedupe behavior for one-shots.
comp/networkpath/npcollector/impl/pathteststore/BUILD.bazel Adds payload + teststatsd deps for new pathteststore tests.
comp/networkpath/npcollector/impl/npcollectorcomp.go Resolves dynamic tests state via core+sysprobe config and emits a state metric.
comp/networkpath/npcollector/impl/npcollector_testutils_test.go Injects sysprobe config mock to support state resolution in component tests.
comp/networkpath/npcollector/impl/npcollector_test.go Updates expected emitted payloads and expected pathtests to include dynamic_test_profile.
comp/networkpath/npcollector/impl/npcollector.go Implements baseline scheduling window + bounded selector, local-vs-remote filter selection, and emits baseline execution metrics.
comp/networkpath/npcollector/impl/config_test.go Updates config enablement tests to use dynamicTestsState instead of connections monitoring boolean.
comp/networkpath/npcollector/impl/config.go Replaces connections-monitoring enable flag with an effective dynamicTestsState, and adds baseline window duration.
comp/networkpath/npcollector/impl/common/pathtest.go Adds baseline metadata (profile, one-shot, execution deadline) to pathtest model.
comp/networkpath/npcollector/impl/baseline_window_test.go Adds tests for baseline window behavior and filter bypass semantics.
comp/networkpath/npcollector/impl/baseline_selector_test.go Adds unit tests and benchmark for bounded baseline selector behavior.
comp/networkpath/npcollector/impl/baseline_selector.go New bounded baseline selector implementation using xxhash + space-saving style replacement.
comp/networkpath/npcollector/impl/BUILD.bazel Adds new selector sources/tests and deps (xxhash, networkpath/config, sysprobeconfig).
comp/metadata/inventoryagent/impl/inventoryagent_test.go Adds baseline tests flag to inventoryagent feature reporting tests.
comp/metadata/inventoryagent/impl/inventoryagent.go Reports baseline tests enabled state in inventory metadata payload.
comp/metadata/inventoryagent/README.md Documents the new inventory feature field for baseline tests.
Suppressed comments (1)

pkg/system-probe/config/config.go:1

  • This mutates system_probe_config.enabled twice during load, once purely to influence ResolveDynamicTestsState(), then again for the final value. That side-effect makes load ordering harder to reason about and increases risk if other code reads config during initialization. A cleaner approach is to avoid intermediate cfg.Set(...) and instead pass the derived sysprobe-enabled value into the resolver (e.g., via a small Reader wrapper that overrides GetBool(systemProbeKey)), then set system_probe_config.enabled exactly once after all modules (including traceroute) are finalized.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread comp/networkpath/npcollector/impl/npcollector_baseline_test.go
Comment thread comp/networkpath/npcollector/impl/baselineselector/baseline_selector_test.go Outdated
Comment thread comp/networkpath/npcollector/impl/pathteststore/pathteststore.go Outdated
Comment thread comp/networkpath/npcollector/impl/baseline_selector.go Outdated
@AlexandreYang

Copy link
Copy Markdown
Member Author

[AI] review-fix-loop: blocked — 1 iteration (cbab65c0409)

  • ✅ Full-diff self-review and focused local validation passed, including race tests
  • ✅ No unresolved review threads; branch is clean and synced
  • ❌ Required skip-qa-check failed in the label-policy step; the review-fix workflow forbids changing labels or rerunning label-caused checks
  • release-note-check, dd-gitlab/default-pipeline, and current-head Codex/Copilot responses are pending
  • devflow/mergegate is in progress (exempt)

@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: cbab65c040

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

Comment thread comp/networkpath/npcollector/impl/npcollectorcomp.go Outdated
Comment thread comp/networkpath/npcollector/impl/pathteststore/pathteststore.go Outdated
Comment thread pkg/networkpath/payload/pathevent.go
@datadog-prod-us1-5

datadog-prod-us1-5 Bot commented Aug 15, 2026

Copy link
Copy Markdown
Contributor

🎯 Code Coverage (details)
Patch Coverage: 90.77%
Overall Coverage: 52.44% (+0.06%)

This comment will be updated automatically if new data arrives.
🔗 Commit SHA: 3f6a287 | Docs | Datadog PR Page | Give us feedback!

@AlexandreYang AlexandreYang changed the title alex/baseline_dynamic_test_for_cnm Add baseline Dynamic Tests for Cloud Network Monitoring Aug 15, 2026
@dd-octo-sts

dd-octo-sts Bot commented Aug 15, 2026

Copy link
Copy Markdown
Contributor

Static quality checks

✅ Please find below the results from static quality gates
Comparison made with ancestor a614467
📊 Static Quality Gates Dashboard
🔗 SQG Job

Successful checks

Info

Quality gate Change Size (prev → curr → max)
agent_deb_amd64 +24.0 KiB (0.00% increase, -0.49% of buffer) 759.674 → 759.697 → 764.500
agent_deb_amd64_fips +24.0 KiB (0.00% increase, -0.73% of buffer) 712.535 → 712.558 → 715.740
agent_heroku_amd64 +8.0 KiB (0.00% increase, -0.11% of buffer) 312.013 → 312.021 → 319.050
agent_msi +15.5 KiB (0.00% increase, -0.09% of buffer) 643.658 → 643.673 → 660.960
agent_rpm_amd64 +24.0 KiB (0.00% increase, -0.49% of buffer) 759.657 → 759.681 → 764.470
agent_rpm_amd64_fips +24.0 KiB (0.00% increase, -0.73% of buffer) 712.518 → 712.542 → 715.740
agent_rpm_arm64 +16.0 KiB (0.00% increase, -1.40% of buffer) 735.422 → 735.438 → 736.540
agent_rpm_arm64_fips +12.0 KiB (0.00% increase, -0.56% of buffer) 691.609 → 691.621 → 693.690
agent_suse_amd64 +24.0 KiB (0.00% increase, -0.49% of buffer) 759.657 → 759.681 → 764.470
agent_suse_amd64_fips +24.0 KiB (0.00% increase, -0.73% of buffer) 712.518 → 712.542 → 715.740
agent_suse_arm64 +16.0 KiB (0.00% increase, -1.40% of buffer) 735.422 → 735.438 → 736.540
agent_suse_arm64_fips +12.0 KiB (0.00% increase, -0.56% of buffer) 691.609 → 691.621 → 693.690
docker_agent_amd64 +24.0 KiB (0.00% increase, -1.34% of buffer) 818.289 → 818.313 → 820.040
docker_agent_arm64 +16.0 KiB (0.00% increase, -0.95% of buffer) 819.098 → 819.114 → 820.740
docker_agent_jmx_amd64 +24.0 KiB (0.00% increase, -1.45% of buffer) 1009.187 → 1009.210 → 1010.800
docker_agent_jmx_arm64 +16.0 KiB (0.00% increase, -0.88% of buffer) 998.648 → 998.664 → 1000.420
docker_dogstatsd_arm64 +64.0 KiB (0.17% increase, -8.80% of buffer) 37.560 → 37.622 → 38.270
iot_agent_deb_amd64 +8.0 KiB (0.02% increase, -0.74% of buffer) 46.475 → 46.483 → 47.530
iot_agent_deb_arm64 +8.0 KiB (0.02% increase, -0.73% of buffer) 43.127 → 43.135 → 44.200
iot_agent_deb_armhf +8.0 KiB (0.02% increase, -0.72% of buffer) 43.910 → 43.918 → 44.990
iot_agent_rpm_amd64 +8.0 KiB (0.02% increase, -0.74% of buffer) 46.476 → 46.483 → 47.530
iot_agent_suse_amd64 +8.0 KiB (0.02% increase, -0.74% of buffer) 46.475 → 46.482 → 47.530
11 successful checks with minimal change (< 2 KiB)
Quality gate Current Size
docker_cluster_agent_amd64 210.475 MiB
docker_cluster_agent_arm64 223.456 MiB
docker_cws_instrumentation_amd64 7.439 MiB
docker_cws_instrumentation_arm64 6.877 MiB
docker_dogstatsd_amd64 39.482 MiB
docker_host_profiler_amd64 305.814 MiB
docker_host_profiler_arm64 317.125 MiB
dogstatsd_deb_amd64 30.224 MiB
dogstatsd_deb_arm64 28.247 MiB
dogstatsd_rpm_amd64 30.224 MiB
dogstatsd_suse_amd64 30.224 MiB

@AlexandreYang

Copy link
Copy Markdown
Member Author

@codex review focus on the new review fixes: baseline-only rDNS activation, recurring TTL-boundary compatibility when baseline is disabled, the baseline packaged-Agent E2E/fakeintake assertions, and removal of inventory exposure. Also review the full PR for correctness, security, concurrency, disabled-state regressions, and test coverage.

@AlexandreYang

Copy link
Copy Markdown
Member Author

@copilot review

@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: c5e261bf3a

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

Comment thread test/new-e2e/tests/netpath/dynamic-tests/host_traffic_dynamic_path_test.go Outdated
Comment thread test/new-e2e/tests/netpath/dynamic-tests/host_traffic_dynamic_path_test.go Outdated
Comment thread comp/rdnsquerier/impl/config.go Outdated
@cit-pr-commenter-54b7da

cit-pr-commenter-54b7da Bot commented Aug 15, 2026

Copy link
Copy Markdown

Regression Detector

Regression Detector Results

Metrics dashboard
Target profiles
Job ID: fedc9824-60be-4e26-8d35-f82a41b1433b

Baseline: a614467
Comparison: 3f6a287
Diff

Optimization Goals: ✅ No significant changes detected

Fine details of change detection per experiment

perf experiment goal Δ mean % Δ mean % CI trials links
quality_gate_logs % cpu utilization +2.82 [+1.95, +3.68] 1 Logs bounds checks dashboard
quality_gate_metrics_logs memory utilization +0.38 [+0.13, +0.62] 1 Logs bounds checks dashboard
quality_gate_security_idle memory utilization +0.05 [-0.06, +0.16] 1 Logs bounds checks dashboard
quality_gate_idle memory utilization +0.04 [-0.08, +0.15] 1 Logs bounds checks dashboard
quality_gate_idle_all_features memory utilization +0.01 [-0.04, +0.05] 1 Logs bounds checks dashboard
quality_gate_security_mean_fs_load memory utilization -0.24 [-0.31, -0.17] 1 Logs bounds checks dashboard
quality_gate_security_no_fs_load memory utilization -0.25 [-0.39, -0.11] 1 Logs bounds checks dashboard
quality_gate_private_action_runner memory utilization -0.53 [-0.65, -0.40] 1 Logs bounds checks dashboard

Bounds Checks: ✅ Passed

perf experiment bounds_check_name replicates_passed observed_value links
quality_gate_idle intake_connections 10/10 4 = 4 bounds checks dashboard
quality_gate_idle memory_usage 10/10 171.25MiB ≤ 178MiB bounds checks dashboard
quality_gate_idle total_bytes_received 10/10 741.81KiB ≤ 819.20KiB bounds checks dashboard
quality_gate_idle_all_features intake_connections 10/10 4 = 4 bounds checks dashboard
quality_gate_idle_all_features memory_usage 10/10 515.09MiB ≤ 538MiB bounds checks dashboard
quality_gate_idle_all_features total_bytes_received 10/10 1.13MiB ≤ 1.25MiB bounds checks dashboard
quality_gate_logs intake_connections 10/10 18 ≤ 40 bounds checks dashboard
quality_gate_logs memory_usage 10/10 203.61MiB ≤ 229MiB bounds checks dashboard
quality_gate_logs missed_bytes 10/10 0B = 0B bounds checks dashboard
quality_gate_logs total_bytes_received 10/10 264.22MiB ≤ 292MiB bounds checks dashboard
quality_gate_metrics_logs cpu_usage 10/10 369.38 ≤ 2000 bounds checks dashboard
quality_gate_metrics_logs intake_connections 10/10 17 ≤ 40 bounds checks dashboard
quality_gate_metrics_logs memory_usage 10/10 400.55MiB ≤ 439MiB bounds checks dashboard
quality_gate_metrics_logs missed_bytes 10/10 0B = 0B bounds checks dashboard
quality_gate_metrics_logs total_bytes_received 10/10 0.94GiB ≤ 1.04GiB bounds checks dashboard
quality_gate_private_action_runner memory_usage 10/10 72.08MiB ≤ 76MiB bounds checks dashboard
quality_gate_security_idle cpu_usage 10/10 27.51 ≤ 100 bounds checks dashboard
quality_gate_security_idle memory_usage 10/10 323.19MiB ≤ 335MiB bounds checks dashboard
quality_gate_security_mean_fs_load cpu_usage 10/10 60.41 ≤ 200 bounds checks dashboard
quality_gate_security_mean_fs_load memory_usage 10/10 304.32MiB ≤ 314MiB bounds checks dashboard
quality_gate_security_no_fs_load cpu_usage 10/10 20.93 ≤ 100 bounds checks dashboard
quality_gate_security_no_fs_load memory_usage 10/10 312.08MiB ≤ 343MiB bounds checks dashboard

Explanation

Confidence level: 90.00%
Effect size tolerance: |Δ mean %| ≥ 5.00%

Performance changes are noted in the perf column of each table:

  • ✅ = significantly better comparison variant performance
  • ❌ = significantly worse comparison variant performance
  • ➖ = no significant change in performance

A regression test is an A/B test of target performance in a repeatable rig, where "performance" is measured as "comparison variant minus baseline variant" for an optimization goal (e.g., ingress throughput). Due to intrinsic variability in measuring that goal, we can only estimate its mean value for each experiment; we report uncertainty in that value as a 90.00% confidence interval denoted "Δ mean % CI".

For each experiment, we decide whether a change in performance is a "regression" -- a change worth investigating further -- if all of the following criteria are true:

  1. Its estimated |Δ mean %| ≥ 5.00%, indicating the change is big enough to merit a closer look.

  2. Its 90.00% confidence interval "Δ mean % CI" does not contain zero, indicating that if our statistical model is accurate, there is at least a 90.00% chance there is a difference in performance between baseline and comparison variants.

  3. Its configuration does not mark it "erratic".

CI Pass/Fail Decision

Passed. All Quality Gates passed.

  • quality_gate_metrics_logs, bounds check missed_bytes: 10/10 replicas passed. Gate passed.
  • quality_gate_metrics_logs, bounds check intake_connections: 10/10 replicas passed. Gate passed.
  • quality_gate_metrics_logs, bounds check total_bytes_received: 10/10 replicas passed. Gate passed.
  • quality_gate_metrics_logs, bounds check cpu_usage: 10/10 replicas passed. Gate passed.
  • quality_gate_metrics_logs, bounds check memory_usage: 10/10 replicas passed. Gate passed.
  • quality_gate_security_idle, bounds check memory_usage: 10/10 replicas passed. Gate passed.
  • quality_gate_security_idle, bounds check cpu_usage: 10/10 replicas passed. Gate passed.
  • quality_gate_security_mean_fs_load, bounds check memory_usage: 10/10 replicas passed. Gate passed.
  • quality_gate_security_mean_fs_load, bounds check cpu_usage: 10/10 replicas passed. Gate passed.
  • quality_gate_logs, bounds check memory_usage: 10/10 replicas passed. Gate passed.
  • quality_gate_logs, bounds check missed_bytes: 10/10 replicas passed. Gate passed.
  • quality_gate_logs, bounds check intake_connections: 10/10 replicas passed. Gate passed.
  • quality_gate_logs, bounds check total_bytes_received: 10/10 replicas passed. Gate passed.
  • quality_gate_idle, bounds check memory_usage: 10/10 replicas passed. Gate passed.
  • quality_gate_idle, bounds check intake_connections: 10/10 replicas passed. Gate passed.
  • quality_gate_idle, bounds check total_bytes_received: 10/10 replicas passed. Gate passed.
  • quality_gate_idle_all_features, bounds check memory_usage: 10/10 replicas passed. Gate passed.
  • quality_gate_idle_all_features, bounds check total_bytes_received: 10/10 replicas passed. Gate passed.
  • quality_gate_idle_all_features, bounds check intake_connections: 10/10 replicas passed. Gate passed.
  • quality_gate_security_no_fs_load, bounds check memory_usage: 10/10 replicas passed. Gate passed.
  • quality_gate_security_no_fs_load, bounds check cpu_usage: 10/10 replicas passed. Gate passed.
  • quality_gate_private_action_runner, bounds check memory_usage: 10/10 replicas passed. Gate passed.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 29 out of 29 changed files in this pull request and generated no new comments.

Suppressed comments (3)

comp/networkpath/npcollector/impl/npcollector.go:292

  • The baseline-mode selection is currently keyed off !connectionsMonitoringEnabled, so if both connectionsMonitoringEnabled and baselineTestsEnabled are true, baseline mode is silently disabled. If that “mutually exclusive” behavior is intended, make it explicit (e.g., warn/log and ignore baseline), or enforce it in config parsing; otherwise, key baselineMode off baselineTestsEnabled (or add a clear precedence rule) so operators don’t end up with a surprising no-op.
func (s *npCollectorImpl) ScheduleNetworkPathTests(conns iter.Seq[npmodel.NetworkPathConnection]) {
	if !s.collectorConfigs.connectionsMonitoringEnabled && !s.collectorConfigs.baselineTestsEnabled {
		return
	}

	baselineMode := !s.collectorConfigs.connectionsMonitoringEnabled
	s.scheduleNetworkPathTests(payload.PathOriginNetworkTraffic, conns, baselineMode)
}

pkg/networkpath/payload/payload_test.go:60

  • Checking JSON field presence via bytes.Contains is brittle (it can produce false positives/negatives if formatting or escaping changes). A more robust assertion is to unmarshal into map[string]any (or a small struct alias) and assert key presence/absence directly.
func TestNetworkPathDynamicTestProfileJSON(t *testing.T) {
	tests := []struct {
		name        string
		profile     DynamicTestProfile
		expectField bool
	}{
		{name: "unset", expectField: false},
		{name: "baseline", profile: DynamicTestProfileBaseline, expectField: true},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			raw, err := json.Marshal(NetworkPath{DynamicTestProfile: tt.profile})
			require.NoError(t, err)
			assert.Equal(t, tt.expectField, bytes.Contains(raw, []byte(`"dynamic_test_profile"`)))
		})
	}
}

test/new-e2e/tests/netpath/dynamic-tests/host_traffic_dynamic_path_test.go:102

  • Passing an untyped empty string to a payload.DynamicTestProfile parameter obscures intent (unset vs. a real profile). Consider adding/using an explicit “unset” value (e.g., payload.DynamicTestProfile("") or a named constant like DynamicTestProfileUnset) to make the expectation self-documenting.
		match := assertHostTrafficNetworkPath(c, netpaths, "", "RC-admitted")

@AlexandreYang

Copy link
Copy Markdown
Member Author

@codex make a comprehensive code and security review

Classify findings as P0 (critical), P1 (high), P2 (substantive), or P3 (optional). Include the priority, file, line, failure scenario, impact, and whether the finding is in scope for this PR.

@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: 8afc6af3e0

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

Comment thread comp/networkpath/npcollector/impl/npcollector.go
- Keep baseline candidate admission governed by built-in and local filters so Dynamic RC remains exclusive to standard tests.
- Add focused coverage proving RC includes and excludes cannot alter baseline selection.

Source: review feedback
Validation: bazel test --nocache_test_results //comp/networkpath/npcollector/impl:impl_test
@AlexandreYang

Copy link
Copy Markdown
Member Author

[AI] review-fix-loop iteration 1 — fixed and pushed (db7b1063af3)

  • ✅ Isolated baseline admission from Dynamic Remote Configuration; standard RC filtering and attribution remain unchanged
  • ✅ Focused uncached collector tests passed
  • ✅ Current-head trusted finding resolved; one older out-of-scope rate-limiter follow-up remains unresolved by design
  • ✅ Branch clean and synced
  • ⏳ Required CI restarted; devflow/mergegate remains exempt

@AlexandreYang

Copy link
Copy Markdown
Member Author

@codex make a comprehensive code and security review

Classify findings as P0 (critical), P1 (high), P2 (substantive), or P3 (optional). Include the priority, file, line, failure scenario, impact, and whether the finding is in scope for this PR.

@AlexandreYang
AlexandreYang requested a lite review from Copilot August 16, 2026 12:40

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 30 out of 30 changed files in this pull request and generated no new comments.

Suppressed comments (3)

comp/networkpath/npcollector/impl/npcollector.go:257

  • Baseline mode evaluates s.localFilter without any synchronization, while standard mode protects s.filter with filterMutex. This is only safe if localFilter is immutable for the lifetime of the collector and never mutated/replaced concurrently (e.g., by remote config updates or config reload). To avoid potential data races and to ensure baseline truly ignores RC, consider either (1) guaranteeing localFilter is a separate, immutable filter built from local config only, or (2) protecting localFilter access with the same mutex / an atomic pointer swap strategy used for filter.
	if baselineMode {
		// Dynamic Remote Configuration admits standard tests only. Baseline
		// selection remains governed by built-in and local filters.
		included, testConfigID, tags = s.localFilter.EvaluateWithTags(conn.Domain, conn.Dest.Addr())
	} else {
		s.filterMutex.RLock()
		included, testConfigID, tags = s.filter.EvaluateWithTags(conn.Domain, conn.Dest.Addr())
		s.filterMutex.RUnlock()
	}

comp/networkpath/npcollector/impl/npcollector.go:343

  • In baseline mode, evaluateNetworkPathForConn computes testConfigID and tags (via EvaluateWithTags), but those values are never applied to the pathtest before it’s selected/scheduled. This drops any tags produced by local/built-in filters for baseline tests. Consider applying evaluation.tags (and any other relevant fields) to pathtest before calling addBaselinePath, or extending addBaselinePath to accept and persist the evaluation output.
		evaluation := s.evaluateNetworkPathForConn(conn, origin, vpcSubnets, baselineMode)
		if !evaluation.shouldSchedule {
			s.logger.Tracef("Skipped connection: addr=%s, protocol=%s", conn.Dest, conn.Type)
			continue
		}
		pathtest := s.makePathtest(conn, origin)
		if baselineMode {
			selectedBaselineCandidates = addBaselinePath(selectedBaselineCandidates, pathtest, conn.Signals)
			continue
		}

comp/networkpath/npcollector/impl/baseline.go:70

  • The baseline ranking byte score sums SentBytes + RecvBytes directly. While overflow is unlikely, it would silently wrap if extremely large counters are present. Consider guarding against overflow (e.g., saturating at math.MaxUint64 or using a checked add) since the result is used for ordering.
func addBaselinePath(selected []baselineCandidate, path common.Pathtest, signals npmodel.ConnectionSignals) []baselineCandidate {
	path.DynamicTestProfile = payload.DynamicTestProfileBaseline
	return addBaselineCandidate(selected, baselineCandidate{
		path:       path,
		pathHash:   path.GetHash(),
		diagnostic: signals.TimeoutCount > 0 || signals.RTOCount > 0 || signals.Retransmits > 0,
		bytes:      signals.SentBytes + signals.RecvBytes,
	})
}

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Keep them coming!

Reviewed commit: db7b1063af

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

- Document that baseline selection is independent of RC admission and attribution.
- Exercise the real RC update path when verifying baseline provenance.

Validation: bazel test --nocache_test_results //comp/networkpath/npcollector/impl:impl_test //pkg/networkpath/payload:payload_test
@AlexandreYang

Copy link
Copy Markdown
Member Author

[AI] Baseline + Dynamic RC consistency update (6c215961cae)

  • ✅ Fully reverted db7b1063af3 via 97ee4b7fe99
  • ✅ Documented in code and the PR description that baseline ranking is independent from RC admission/attribution
  • ✅ Strengthened baseline provenance coverage through the real RC update path
  • ✅ Focused collector and payload tests passed
  • ✅ Branch clean and synced
  • ⏳ Restarted CI is pending with no failures

- Document the shared RC filter where baseline and standard scheduling diverge, making the attribution flow explicit.

Validation: bazel test --nocache_test_results //comp/networkpath/npcollector/impl:impl_test
- Keep the compatibility invariant beside the baseline profile assignment where provenance must remain unchanged.

Validation: bazel test --nocache_test_results //comp/networkpath/npcollector/impl:impl_test
@AlexandreYang

Copy link
Copy Markdown
Member Author

@codex make a comprehensive code and security review

Classify findings as P0 (critical), P1 (high), P2 (substantive), or P3 (optional). Include the priority, file, line, failure scenario, impact, and whether the finding is in scope for this PR.

@AlexandreYang
AlexandreYang requested a lite review from Copilot August 16, 2026 13:14

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 29 out of 29 changed files in this pull request and generated no new comments.

Suppressed comments (5)

comp/networkpath/npcollector/impl/baseline_test.go:7

  • This test file is guarded by //go:build test, so it will be skipped by default go test unless CI/Bazel explicitly sets the test build tag. If the rest of the repo’s Go unit tests aren’t consistently run with that tag, consider removing the build tag (mandatory if it would otherwise be skipped), or ensure the Bazel dd_agent_go_test target for this package sets the required build tags so these baseline-selection tests always execute in CI.
//go:build test

package npcollectorimpl

pkg/networkpath/payload/payload_test.go:58

  • Using bytes.Contains on the marshaled JSON is a bit brittle (it can miss subtle regressions like a renamed field, or pass accidentally if the substring appears elsewhere). A more robust test is to unmarshal into map[string]any (or a small struct) and assert key presence/absence and, when present, the expected value (e.g., \"baseline\").
			raw, err := json.Marshal(NetworkPath{DynamicTestProfile: tt.profile})
			require.NoError(t, err)
			assert.Equal(t, tt.expectField, bytes.Contains(raw, []byte(`"dynamic_test_profile"`)))
		})

test/new-e2e/tests/netpath/dynamic-tests/host_traffic_dynamic_path_common_test.go:261

  • After configureAgentResolver() the test only asserts DNS resolution, but it no longer verifies that the service is reachable via the domain name. Since the generator intentionally swallows request exceptions, a misroute/firewall issue can turn into a slow ‘no netpath events’ timeout later. Consider adding a fast reachability check here (e.g., an HTTP GET from the generator host to http://<domain>/) so failures are detected early with clearer logs.
func (s *hostTrafficDynamicPathBaseSuite) assertHostTrafficDomainResolves() {
	output := s.Env().RemoteHost.MustExecute("getent ahostsv4 " + shellQuote(hostTrafficRemoteConfigDomain))
	require.Contains(s.T(), output, s.Env().HTTPBinHost.Address)
}

test/new-e2e/tests/netpath/dynamic-tests/host_traffic_dynamic_path_common_test.go:69

  • Now that hostTrafficDynamicPathProvisioner(...) is reused by multiple suites (baseline + RC-admitted), the EC2 instance naming/resource identifiers are still hard-coded (hosttrafficdynamicpathvm, hosttraffichttpbinvm). If these suites ever run concurrently in the same Pulumi project/stack (or if the test runner changes parallelism), this increases the risk of resource-name collisions. Consider incorporating the name parameter into the VM names/resource identifiers (e.g., prefix/suffix) to keep resources unique per suite.
		params := ec2.GetParams(
			ec2.WithName("hosttrafficdynamicpathvm"),
			ec2.WithAgentOptions(
				agentparams.WithAgentConfig(agentConfig),
				agentparams.WithSystemProbeConfig(systemProbeConfig),
			),
		)

test/new-e2e/tests/netpath/dynamic-tests/host_traffic_dynamic_path_common_test.go:74

  • Now that hostTrafficDynamicPathProvisioner(...) is reused by multiple suites (baseline + RC-admitted), the EC2 instance naming/resource identifiers are still hard-coded (hosttrafficdynamicpathvm, hosttraffichttpbinvm). If these suites ever run concurrently in the same Pulumi project/stack (or if the test runner changes parallelism), this increases the risk of resource-name collisions. Consider incorporating the name parameter into the VM names/resource identifiers (e.g., prefix/suffix) to keep resources unique per suite.
		httpbinHost, err := ec2.NewVM(awsEnv, "hosttraffichttpbinvm")

@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: dc92f11b85

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

Comment thread test/new-e2e/tests/netpath/dynamic-tests/host_traffic_dynamic_path_common_test.go Outdated
- Recreate the original resolver symlink target without resolving relative paths from the command working directory.
- Preserve resolver-manager ownership across same-infrastructure E2E retries.

Source: review feedback
Validation: bazel build //test/new-e2e/tests/netpath/dynamic-tests:dynamic-tests_test
@AlexandreYang

Copy link
Copy Markdown
Member Author

[AI] review-fix-loop iteration 1 — fixed and pushed (130487643be)

  • ✅ Restored relative and absolute resolver symlinks verbatim for retry-safe E2E cleanup
  • ✅ Netpath Dynamic Tests E2E binary builds successfully
  • ✅ Current-head actionable thread resolved; one older out-of-scope rate-limiter follow-up remains unresolved
  • ✅ Branch clean and synced
  • ⏳ Required CI restarted; devflow/mergegate remains exempt

@AlexandreYang

Copy link
Copy Markdown
Member Author

@codex make a comprehensive code and security review

Classify findings as P0 (critical), P1 (high), P2 (substantive), or P3 (optional). Include the priority, file, line, failure scenario, impact, and whether the finding is in scope for this PR.

@AlexandreYang
AlexandreYang requested a lite review from Copilot August 16, 2026 13:20

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 29 out of 29 changed files in this pull request and generated 1 comment.

Suppressed comments (1)

test/new-e2e/tests/netpath/dynamic-tests/host_traffic_dynamic_path_common_test.go:257

  • This helper now validates only DNS resolution, whereas the prior flow also validated the service was reachable via the configured domain after the resolver switch. Adding a small HTTP check here (using the same Python/urllib approach used elsewhere in this file) would fail fast with a clearer error when DNS/HTTP wiring is broken, instead of timing out later waiting for netpath events.
func (s *hostTrafficDynamicPathBaseSuite) assertHostTrafficDomainResolves() {
	output := s.Env().RemoteHost.MustExecute("getent ahostsv4 " + shellQuote(hostTrafficRemoteConfigDomain))
	require.Contains(s.T(), output, s.Env().HTTPBinHost.Address)
}

Comment thread test/new-e2e/tests/netpath/dynamic-tests/host_traffic_dynamic_path_common_test.go Outdated
- Resolve saved relative symlink targets against /etc before validating them.
- Restore the static backup when the original target disappeared, while preserving valid resolver-manager symlinks verbatim.

Source: review feedback
Validation: bazel build //test/new-e2e/tests/netpath/dynamic-tests:dynamic-tests_test
@AlexandreYang

Copy link
Copy Markdown
Member Author

[AI] review-fix-loop iteration 2 — fixed and pushed (3f6a287baca)

  • ✅ Preserved valid relative/absolute resolver symlinks and added a safe static-backup fallback for stale targets
  • ✅ Netpath Dynamic Tests E2E binary builds successfully
  • ✅ Current-head actionable thread resolved; one older out-of-scope rate-limiter follow-up remains unresolved
  • ✅ Branch clean and synced
  • ⏳ Required CI restarted; devflow/mergegate remains exempt

@AlexandreYang

Copy link
Copy Markdown
Member Author

@codex make a comprehensive code and security review

Classify findings as P0 (critical), P1 (high), P2 (substantive), or P3 (optional). Include the priority, file, line, failure scenario, impact, and whether the finding is in scope for this PR.

@AlexandreYang
AlexandreYang requested a lite review from Copilot August 16, 2026 13:24

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 29 out of 29 changed files in this pull request and generated no new comments.

Suppressed comments (3)

test/new-e2e/tests/netpath/dynamic-tests/host_traffic_dynamic_path_common_test.go:265

  • assertHostTrafficDomainResolves now only verifies DNS resolution, but not that the service is reachable via the domain after the resolver switch. This can lead to long test timeouts later (generator runs, fakeintake waits) when HTTP access fails despite successful getent. Consider adding a fast reachability check here (e.g., a short python3/curl request to http://<domain>/) so the suite fails early with clearer diagnostics.
func (s *hostTrafficDynamicPathBaseSuite) assertHostTrafficDomainResolves() {
	output := s.Env().RemoteHost.MustExecute("getent ahostsv4 " + shellQuote(hostTrafficRemoteConfigDomain))
	require.Contains(s.T(), output, s.Env().HTTPBinHost.Address)
}

test/new-e2e/tests/netpath/dynamic-tests/host_traffic_dynamic_path_common_test.go:103

  • The refactor replaces the previous curl-based checks/generator with multiple python3 invocations (HTTP server, DNS server, generator, reachability checks). If the E2E images ever change and python3 is missing on either host, failures will be less actionable (“command not found”) and harder to diagnose. Consider adding an explicit prerequisite check/install step (similar to the previous curl installation guard) for python3 on both RemoteHost and HTTPBinHost, or at least failing fast with a targeted message when python3 is unavailable.
func (s *hostTrafficDynamicPathBaseSuite) setupHostTraffic() {
	s.startHostTrafficHTTPServer()
	s.startHostTrafficDNSServer()
	s.assertHostTrafficServiceReady()
	s.assertHostTrafficServiceReachable()
	s.configureAgentResolver()
	s.assertHostTrafficDomainResolves()
}

pkg/networkpath/payload/payload_test.go:58

  • Using bytes.Contains on the raw JSON to detect field presence is relatively brittle (it depends on string matching rather than JSON structure). A more robust approach is to unmarshal into map[string]any (or a small struct) and assert whether the dynamic_test_profile key exists, which will keep the test stable across potential encoding changes while still validating omitempty behavior.
			raw, err := json.Marshal(NetworkPath{DynamicTestProfile: tt.profile})
			require.NoError(t, err)
			assert.Equal(t, tt.expectField, bytes.Contains(raw, []byte(`"dynamic_test_profile"`)))
		})

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. 👍

Reviewed commit: 3f6a287bac

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

@AlexandreYang

Copy link
Copy Markdown
Member Author

[AI] review-fix-loop: clean — 3 iterations (2 repair iterations + final verification)

  • ✅ Current head 3f6a287 explicitly cleared by Codex and Copilot with no new findings
  • ✅ Fixed resolver restoration to preserve valid relative/absolute symlinks and safely fall back when a saved target is stale (1304876, 3f6a287)
  • ✅ Focused Bazel tests/builds passed, including the npcollector implementation tests, payload tests, and Dynamic Tests E2E binary build
  • ✅ All non-exempt required checks are green; devflow/mergegate is the only pending exempt check
  • ✅ Branch is clean, pushed, synchronized with the PR head, and 0 commits behind the base branch
  • ℹ️ One outdated unresolved rate-limiter thread remains as an out-of-scope follow-up; this PR removed the one-shot path involved and the referenced store code matches the base branch

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants