Skip to content

feat(ping): implement ping builtin#118

Merged
AlexandreYang merged 63 commits intomainfrom
alex/ping-v4
Mar 18, 2026
Merged

feat(ping): implement ping builtin#118
AlexandreYang merged 63 commits intomainfrom
alex/ping-v4

Conversation

@AlexandreYang
Copy link
Copy Markdown
Member

@AlexandreYang AlexandreYang commented Mar 17, 2026

Summary

  • Implements ping builtin using github.com/prometheus-community/pro-bing
  • Supports -c, -W, -i, -q, -4, -6, -h flags with safety caps
  • Dangerous flags (-f, -b, -s, -I, -p, -R) are rejected at flag parse time
  • Broadcast, multicast, and unspecified destinations rejected before sending
  • Integer/float seconds accepted for -W and -i (iputils ping compatibility)
  • Hard 120s execution ceiling; all inputs clamped to safe ranges with warnings
  • Unprivileged ICMP first, auto-fallback to privileged raw socket on EPERM

@AlexandreYang
Copy link
Copy Markdown
Member Author

Plan: Implement ping Builtin

Context

The rshell4 project implements a safe shell interpreter for AI agents. The user wants to add a ping builtin that uses the github.com/prometheus-community/pro-bing library for ICMP echo requests. Unlike file-processing builtins, ping is a pure network command with no file access requirements.


Approved Design

Flags to implement

Flag Default Safety cap Description
-c count 4 max 20 Number of ICMP packets to send
-W timeout 1s max 30s Per-reply wait timeout
-i interval 1s min 200ms Interval between packets
-q false Quiet: print only summary
-4 false Force IPv4
-6 false Force IPv6
-h / --help Print usage to stdout, exit 0

Dangerous flags not implemented (rejected by pflag as unknown):

  • -f flood (DoS vector)
  • -b broadcast (network DoS)
  • -s packetsize
  • -I/-i interface binding (not needed; -i is used for interval)
  • -p pattern
  • -R record route

Privilege mode: auto-detect

  1. Create pinger with SetPrivileged(false) (unprivileged UDP-based ICMP)
  2. Run; if error contains "operation not permitted" or syscall.EPERM / syscall.EACCES, create a fresh pinger and retry with SetPrivileged(true)
  3. Document this behavior in the package comment

Output format (matching real ping)

PING <host> (<ip>): 56 data bytes
<nbytes> bytes from <ip>: icmp_seq=<seq> ttl=<ttl> time=<rtt> ms
...
--- <host> ping statistics ---
<sent> packets transmitted, <recv> received, <loss>% packet loss
round-trip min/avg/max/stddev = <min>/<avg>/<max>/<stddev> ms
  • In quiet mode (-q): suppress per-packet lines, print only the final two lines.
  • Exit 0 if at least one packet received; exit 1 otherwise.

Safety constraints

  • count clamped to [1, 20]
  • interval clamped to [200ms, 60s]
  • W (per-reply timeout) clamped to [100ms, 30s]
  • Hard total timeout = count × (interval + W) + 5s grace, capped at 120s; passed to RunWithContext
  • Check ctx.Err() via RunWithContext — no manual loops needed

Rounding of RTT output

Match real ping: use %.3f ms for RTT values.


Files to create/modify

File Action
builtins/ping/ping.go Create — builtin implementation (package ping)
builtins/ping/ping_test.go Create — main Go tests (package ping_test)
builtins/ping/ping_unix_test.go Create — Unix-specific tests (build tag unix)
builtins/ping/ping_fuzz_test.go Create — fuzz tests
builtins/ping/builtin_ping_pentest_test.go Create — pentest tests
interp/register_builtins.go Modify — import and register ping.Cmd
go.mod / go.sum Modify — add github.com/prometheus-community/pro-bing
tests/scenarios/cmd/ping/ Create — YAML scenario tests

Implementation outline for builtins/ping/ping.go

package ping

import (
    "context"
    "errors"
    "fmt"
    "net"
    "syscall"
    "time"

    probing "github.com/prometheus-community/pro-bing"
    "github.com/DataDog/rshell/builtins"
)

const (
    defaultCount    = 4
    maxCount        = 20
    defaultInterval = time.Second
    minInterval     = 200 * time.Millisecond
    defaultTimeout  = time.Second
    maxTimeout      = 30 * time.Second
)

var Cmd = builtins.Command{
    Name:        "ping",
    Description: "send ICMP echo requests to a network host",
    MakeFlags:   registerFlags,
}

func registerFlags(fs *builtins.FlagSet) builtins.HandlerFunc {
    help     := fs.BoolP("help", "h", false, "print usage and exit")
    count    := fs.IntP("count", "c", defaultCount, "number of packets to send (1–20)")
    wait     := fs.DurationP("timeout", "W", defaultTimeout, "time to wait for each reply")
    interval := fs.DurationP("interval", "i", defaultInterval, "interval between packets (min 200ms)")
    quiet    := fs.BoolP("quiet", "q", false, "quiet output (summary only)")
    ipv4     := fs.BoolP("ipv4", "4", false, "use IPv4")
    ipv6     := fs.BoolP("ipv6", "6", false, "use IPv6")

    return func(ctx context.Context, callCtx *builtins.CallContext, args []string) builtins.Result {
        if *help {
            printHelp(callCtx, fs)
            return builtins.Result{}
        }
        if len(args) == 0 {
            callCtx.Errf("ping: missing host operand\nTry 'ping --help' for more information.\n")
            return builtins.Result{Code: 1}
        }
        if len(args) > 1 {
            callCtx.Errf("ping: too many arguments\n")
            return builtins.Result{Code: 1}
        }

        host := args[0]

        // Clamp numeric inputs.
        c  := clampInt(*count, 1, maxCount)
        w  := clampDuration(*wait, 100*time.Millisecond, maxTimeout)
        iv := clampDuration(*interval, minInterval, 60*time.Second)

        // Compute a hard total deadline.
        totalTimeout := time.Duration(c)*(iv+w) + 5*time.Second
        if totalTimeout > 120*time.Second {
            totalTimeout = 120 * time.Second
        }
        ctx, cancel := context.WithTimeout(ctx, totalTimeout)
        defer cancel()

        return runPing(ctx, callCtx, host, c, w, iv, *quiet, *ipv4, *ipv6)
    }
}

func runPing(...) builtins.Result {
    // 1. Create pinger, configure, set callbacks
    // 2. Try unprivileged; on EPERM/EACCES retry privileged
    // 3. Print header, per-packet lines, summary
    // 4. Return exit 0 if recv>0, else 1
}

func isPermissionErr(err error) bool {
    var sErr *net.OpError
    if errors.As(err, &sErr) {
        return errors.Is(sErr.Err, syscall.EPERM) || errors.Is(sErr.Err, syscall.EACCES)
    }
    // String fallback for other platforms
    return strings.Contains(err.Error(), "operation not permitted") ||
           strings.Contains(err.Error(), "access is denied")
}

Test strategy

YAML scenarios (tests/scenarios/cmd/ping/)

All marked skip_assert_against_bash: true (network-dependent; host-specific output).

  • errors/missing_host.yaml — no arguments → exit 1
  • errors/too_many_args.yaml — two args → exit 1
  • errors/unknown_flag.yaml-f → exit 1
  • errors/zero_count.yaml-c 0 → clamped to 1
  • flags/help_flag.yamlping --help → exit 0, stdout contains "Usage"

Go tests (builtins/ping/ping_test.go)

Network-dependent tests call t.Skip("requires network") unless RSHELL_NET_TEST=1.

  • TestPingHelp--help prints usage to stdout, exit 0
  • TestPingMissingHost — no args → exit 1
  • TestPingTooManyArgs — two args → exit 1
  • TestPingUnknownFlag-f rejected → exit 1
  • TestPingCountClamp-c 0 clamped to 1 (no crash)
  • TestPingIntervalClamp-i 10ms clamped to 200ms
  • TestPingQuietFlag — with RSHELL_NET_TEST: quiet output format
  • TestPingIPv4Flag — with RSHELL_NET_TEST: -4 localhost
  • TestPingContextCancel — context cancelled → RunWithContext returns promptly

Pentest tests (builtins/ping/builtin_ping_pentest_test.go)

  • TestPingPentestFlood-f rejected
  • TestPingPentestBroadcast — no -b flag exists → unknown flag
  • TestPingPentestOverflowCount-c 999999999 clamped
  • TestPingPentestLongHostname — 10000-char hostname → error, no crash
  • TestPingPentestShellInjection; rm -rf / in host → no execution
  • TestPingPentestContextTimeout — short deadline → RunWithContext exits cleanly

Verification

# Unit tests (no network needed)
go test ./builtins/ping/ -run 'TestPing(Help|Missing|TooMany|Unknown|Clamp)' -v

# Network tests (opt-in)
RSHELL_NET_TEST=1 go test ./builtins/ping/ -v -timeout 60s

# Scenario tests
go test ./tests/... -run TestShellScenarios -v

# gofmt check
gofmt -l ./builtins/ping/

# Build check
go build ./...

Adds a ping builtin that sends ICMP echo requests using
github.com/prometheus-community/pro-bing. Supports -c (count, max 20),
-W (per-reply timeout), -i (interval, min 200ms), -q (quiet), -4/-6
(force address family). Dangerous flags (-f flood, -b broadcast, -s
size, -I interface, -p pattern, -R record-route) are rejected.

Auto-detects privilege: tries unprivileged UDP-based ICMP first,
falls back to raw socket on EPERM/EACCES. Enforces a hard total
deadline capped at 120s.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link
Copy Markdown
Member Author

@AlexandreYang AlexandreYang left a comment

Choose a reason for hiding this comment

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

Review Summary

Reviewed the ping builtin implementation. The overall design is solid: input clamping, context deadlines with a 120s hard cap, blocked dangerous flags, unprivileged-first with privilege fallback, comprehensive pentest and fuzz test coverage. Two blocking issues will cause CI to fail before this can merge.


Overall assessment: needs fixes

# Priority File Finding
1 P1 interp/register_builtins.go:57 ping.Cmd indented with one tab instead of three — gofmt CI fails
2 P1 LICENSE-3rdparty.csv (not in diff) github.com/prometheus-community/pro-bing added to go.mod but absent from LICENSE-3rdparty.csvTestComplianceLicense3rdPartyCompleteness will fail. Add: github.com/prometheus-community/pro-bing,https://github.com/prometheus-community/pro-bing,MIT,"Copyright 2022 The Prometheus Authors; Copyright 2016 Cameron Sparr and contributors"
3 P2 tests/scenarios/cmd/ping/errors/ Several scenario tests use stderr_contains instead of preferred expect.stderr (AGENTS.md convention)
4 P3 builtins/ping/ping.go:159 Privilege-escalation fallback does a redundant DNS resolution — buildPinger resolves DNS then SetIPAddr immediately overwrites it

Positive observations

  • Input clamping for -c, -W, and -i with hard upper caps prevents resource exhaustion.
  • Hard 120-second total deadline ensures the builtin cannot block indefinitely.
  • Dangerous flags (-f, -b, -s, -I, -p, -R) are correctly blocked via pflag's unknown-flag rejection — no explicit deny-list needed.
  • isPermissionErr uses errors.Is chain traversal with a string-based fallback for Windows, which is the correct cross-platform approach.
  • Unprivileged-first strategy avoids requesting raw socket capabilities unnecessarily.
  • Fuzz targets (FuzzPingFlags, FuzzPingHostname) with seed corpus cover the main attack surfaces.
  • No filesystem access, os/exec, or unsafe in the implementation.

Comment thread interp/register_builtins.go Outdated
Comment thread tests/scenarios/cmd/ping/errors/flood_flag_rejected.yaml Outdated
Comment thread builtins/ping/ping.go Outdated
@AlexandreYang
Copy link
Copy Markdown
Member Author

@codex review this PR

Important: Read the SPECS section of the PR description. If SPECS are present: make sure the implementation matches ALL the specs.
The specs override other instructions (code, inline comments in code, etc). ALL specs MUST be implemented.

@AlexandreYang
Copy link
Copy Markdown
Member Author

Iteration 1 self-review result: REQUEST_CHANGES

Findings: 4 total (2×P1, 1×P2, 1×P3)

Summary:

  • P1: interp/register_builtins.go has a gofmt formatting issue (ping.Cmd indented with 1 tab instead of 3) — will fail CI
  • P1: LICENSE-3rdparty.csv is missing the github.com/prometheus-community/pro-bing v0.8.0 entry — TestComplianceLicense3rdPartyCompleteness will fail
  • P2: 4 test scenario files use stderr_contains instead of the preferred expect.stderr exact-match field
  • P3: Inefficiency in buildPinger fallback (double DNS resolution)

… comment

- Fix gofmt indentation for ping.Cmd in interp/register_builtins.go
- Add pro-bing, google/uuid, golang.org/x/net, golang.org/x/sync to
  LICENSE-3rdparty.csv (TestComplianceLicense3rdPartyCompleteness)
- Replace stderr_contains with expect.stderr in flood/broadcast/unknown
  flag rejection scenarios (AGENTS.md convention)
- Add comment explaining the redundant DNS lookup in privilege fallback

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@AlexandreYang
Copy link
Copy Markdown
Member Author

[Claude Sonnet 4.6] Addressed review feedback from @AlexandreYang:

  • P1 gofmt indentation: Fixed ping.Cmd to use 3 tabs in interp/register_builtins.go
  • P1 LICENSE-3rdparty.csv: Added pro-bing, google/uuid, golang.org/x/net, golang.org/x/syncTestComplianceLicense3rdPartyCompleteness now passes
  • P2 stderr_contains → expect.stderr: Updated flood_flag_rejected.yaml, broadcast_flag_rejected.yaml, and unknown_flag.yaml with exact pflag error messages
  • P3 redundant DNS: Added a comment in the privilege fallback explaining why the second DNS lookup is wasted and that there's no NewPingerWithoutResolve API to avoid it

Copy link
Copy Markdown

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

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: 4a44531948

ℹ️ 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 interp/register_builtins.go Outdated
Comment thread builtins/ping/ping.go
Comment thread builtins/ping/ping.go Outdated
Copy link
Copy Markdown
Member Author

@AlexandreYang AlexandreYang left a comment

Choose a reason for hiding this comment

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

Review Summary

Reviewed the ping builtin implementation (PR #118). The core logic, security model, test coverage, and documentation are well-structured. However, the PR is blocked by 3 failing CI checks that must be fixed before merging.

Findings

# Priority File Finding
1 P1 Badge allowedsymbols/symbols_builtins.go (missing from PR) ping entry missing from builtinPerCommandSymbols; symbols not whitelisted — breaks all CI platforms
2 P1 Badge builtins/ping/ping_internal_test.go:99 gofmt failure: comment alignment in TestDurToMS (already fixed locally but not committed)
3 P2 Badge builtins/ping/ping_fuzz_test.go:66 FuzzPingFlags metacharacter filter missing " — fuzz corpus entry 8b2be070e8ff0a61 contains a double-quote that reaches the shell parser unescaped, causing reached EOF without closing quote

Positive observations

  • Excellent security posture: all DoS-capable flags (-f, -b, -s, -I, -p, -R) are explicitly blocked and tested
  • Hard total timeout cap (120s) and per-field clamping prevent resource exhaustion
  • Context cancellation properly propagated through RunWithContext
  • Unprivileged → privileged fallback is sound and handles error chain correctly
  • Comprehensive pentest and fuzz test suites
  • Scenario tests all have skip_assert_against_bash: true (correct — bash ping output varies by system)

Overall: needs fixes (3 items, 2×P1 blocking CI)

Comment thread builtins/ping/ping_fuzz_test.go Outdated
Comment thread builtins/ping/ping_internal_test.go Outdated
@AlexandreYang
Copy link
Copy Markdown
Member Author

P1 Badge `allowedsymbols/symbols_builtins.go` not updated — breaking all CI test runs

The `ping` builtin uses several symbols and one third-party package that are not in the allowlist, and the per-command entry is missing entirely. This causes `TestBuiltinAllowedSymbols`, `TestBuiltinPerCommandSymbols`, and `TestVerificationBuiltinsCleanPass` to fail on all CI platforms (Ubuntu, macOS, Windows).

What needs to be added to `allowedsymbols/symbols_builtins.go`:

  1. Add a `"ping"` entry to `builtinPerCommandSymbols` with all symbols the builtin uses.
  2. Add the following to `builtinAllowedSymbols` (the global ceiling):
"ping": {
    "context.Context",                                         // deadline/cancellation plumbing; pure interface, no side effects.
    "context.WithTimeout",                                     // creates a child context with a deadline; no I/O.
    "errors.Is",                                               // error comparison via chain; pure function, no I/O.
    "fmt.Sprintf",                                             // string formatting; pure function, no I/O.
    "strings.Contains",                                        // substring search; pure function, no I/O.
    "strings.ToLower",                                         // string case conversion; pure function, no I/O.
    "syscall.EACCES",                                          // POSIX errno constant for permission denied; pure constant.
    "syscall.EPERM",                                           // POSIX errno constant for operation not permitted; pure constant.
    "time.Duration",                                           // duration type; pure type, no I/O.
    "time.Millisecond",                                        // duration constant; pure constant.
    "time.Second",                                             // duration constant; pure constant.
    "github.com/prometheus-community/pro-bing.NewPinger",      // creates an ICMP pinger; network I/O required for ping to function.
    "github.com/prometheus-community/pro-bing.NoopLogger{}",   // no-op logger disabling pro-bing internal logging; no side effects.
    "github.com/prometheus-community/pro-bing.Packet",         // ICMP packet descriptor; pure data type.
    "github.com/prometheus-community/pro-bing.Pinger",         // ICMP pinger type; network I/O required for ping to function.
    "github.com/prometheus-community/pro-bing.Statistics",     // ping statistics type; pure data type.
},

Note: `github.com/prometheus-community/pro-bing` is a third-party package. The allowlist system will need to accommodate it as a network-capable import (similar to how `net.*` symbols are allowed for `ip` and `ss`). Check the `ExemptImport` or `BannedPackages` logic in the allowlist system to ensure it doesn't get blocked by the permanent banned-packages list.

@AlexandreYang
Copy link
Copy Markdown
Member Author

@codex review this PR

Important: Read the SPECS section of the PR description. If SPECS are present: make sure the implementation matches ALL the specs.
The specs override other instructions (code, inline comments in code, etc). ALL specs MUST be implemented.

@AlexandreYang
Copy link
Copy Markdown
Member Author

Iteration 1 self-review result: COMMENT

2×P1, 1×P2 findings:

  • P1: allowedsymbols/symbols_builtins.go missing entirely from the PR — causes TestBuiltinAllowedSymbols, TestBuiltinPerCommandSymbols to fail on all platforms
  • P1: ping_internal_test.go:99 gofmt failure (comment alignment) — already fixed locally but not committed
  • P2: ping_fuzz_test.go:66 FuzzPingFlags filter missing " — fuzz corpus entry causes shell parse error

Proceeding to fix these.

- Add ping entry to builtinPerCommandSymbols with all required symbols
- Add missing stdlib symbols (context.WithTimeout, strings.Contains,
  syscall.EACCES/EPERM, time.Millisecond) to builtinAllowedSymbols
- Add pro-bing package symbols to builtinAllowedSymbols
- Fix gofmt misalignment in TestDurToMS comment (ping_internal_test.go)
- Add '"' to FuzzPingFlags metacharacter filter to prevent fuzz corpus
  entries with unescaped double-quotes from causing shell parse errors

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Copy link
Copy Markdown

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

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: e90fff23ba

ℹ️ 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 builtins/ping/ping.go Outdated
Comment thread builtins/ping/ping.go
AlexandreYang and others added 3 commits March 18, 2026 00:30
…pace

The fuzz engine found a '\''\'' (single quote) in the generated flag+value
string that caused a shell parse error. Also exclude backslash and space
since they can similarly break the shell script template.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ll-safe chars

Replace the character denylist with an allowlist: only letters, digits,
hyphens, and dots are permitted in flag+value. This prevents the fuzzer
from generating inputs with shell metacharacters (parens, brackets, etc.)
that cause spurious parse errors unrelated to ping flag handling.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ters

Apply the same allowlist approach as FuzzPingFlags: only allow letters,
digits, hyphens, dots, and colons (for IPv6) in the hostname argument.
This prevents shell parse errors from characters like '(' that the
previous denylist did not cover.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@AlexandreYang
Copy link
Copy Markdown
Member Author

@codex review this PR

Important: Read the SPECS section of the PR description. If SPECS are present: make sure the implementation matches ALL the specs.
The specs override other instructions (code, inline comments in code, etc). ALL specs MUST be implemented.

Copy link
Copy Markdown
Member Author

@AlexandreYang AlexandreYang left a comment

Choose a reason for hiding this comment

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

Iteration 2 self-review — COMMENT (REQUEST_CHANGES intent)

2 P2 findings remain. Both are in buildPinger in builtins/ping/ping.go.

# Priority File Finding
1 P2 builtins/ping/ping.go:191 DNS resolution not bounded by runCtx context deadline
2 P2 builtins/ping/ping.go:199-202 Conflicting -4/-6 flags silently prefer IPv4 instead of rejecting

Comment thread builtins/ping/ping.go Outdated
Comment thread builtins/ping/ping.go
@AlexandreYang
Copy link
Copy Markdown
Member Author

Iteration 2 self-review result: COMMENT (2 findings).

Summary: 2 P2 findings remain — both in buildPinger in builtins/ping/ping.go:

  1. P2: DNS resolution (probing.NewPinger) not bounded by runCtx context deadline
  2. P2: Conflicting -4/-6 flags silently prefer IPv4 instead of returning an error

Fixing both now.

- buildPinger now accepts a ctx parameter and calls probing.NewPinger in
  a goroutine, selecting on ctx.Done() so that DNS resolution is bounded
  by the runCtx deadline (fixes P2: DNS not bounded by context)
- Add explicit mutual-exclusion check: -4 and -6 together now return an
  error instead of silently preferring IPv4 (fixes P2: conflicting flags)
- Add fmt.Errorf to ping per-command allowlist in symbols_builtins.go
- Add scenario test for -4/-6 conflict

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Copy link
Copy Markdown

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

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: 0d5ea98ecd

ℹ️ 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 builtins/ping/ping.go Outdated
Comment thread builtins/ping/ping.go
@AlexandreYang
Copy link
Copy Markdown
Member Author

@codex review this PR

Important: Read the SPECS section of the PR description. If SPECS are present: make sure the implementation matches ALL the specs.
The specs override other instructions (code, inline comments in code, etc). ALL specs MUST be implemented.

Copy link
Copy Markdown
Member Author

@AlexandreYang AlexandreYang left a comment

Choose a reason for hiding this comment

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

Iteration 3 self-review — APPROVE (no new findings)

Reviewed commit 12e94b5 which adds:

  • Context-aware DNS resolution in buildPinger (goroutine + select ctx.Done())
  • Mutual-exclusion check for -4/-6 flags
  • fmt.Errorf added to ping per-command allowlist
  • Scenario test for -4 -6 conflict

Security

  • DNS resolution now bounded by runCtx deadline ✓
  • Conflicting flags rejected with clear error message ✓
  • No new imports; no banned symbols ✓
  • No filesystem access outside sandbox ✓

Correctness

  • buildPinger accepts ctx as first parameter; both callers pass ctx
  • Retry path (privileged fallback) passes already-resolved IP string to avoid redundant DNS ✓
  • Mutual exclusion check before DNS resolution ✓
  • allowedsymbols tests pass ✓

Test coverage

  • New scenario ipv4_ipv6_conflict.yaml covers the mutual-exclusion error path ✓
  • All ping tests pass ✓

CI

  • All checks passing except Allowed Symbols Label Check (human-gated per AGENTS.md) ✓

Overall: no findings. PR is clean pending human review of allowed symbols.

@AlexandreYang
Copy link
Copy Markdown
Member Author

Iteration 3 self-review result: APPROVE (no findings on commit 12e94b5). All P2 findings from iterations 1-2 are resolved. CI is clean except the human-gated Allowed Symbols Label Check.

Copy link
Copy Markdown

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

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: 12e94b5712

ℹ️ 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 builtins/ping/ping.go Outdated
buildPinger now calls net.ResolveIPAddr(resolveNet, host) in the
goroutine where resolveNet is "ip4", "ip6", or "ip" depending on flags.
This ensures dual-stack hosts resolve to the correct address family when
-4 or -6 is specified, fixing the P1 finding.

The resolved IP string is passed to probing.NewPinger which returns
immediately (no second DNS round-trip). The original host argument is
preserved in execPing for display in the PING header and statistics
footer so output still shows the hostname, not the raw IP.

Also adds net.IPAddr and net.ResolveIPAddr to the allowlist.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@AlexandreYang
Copy link
Copy Markdown
Member Author

@codex review this PR

Important: Read the SPECS section of the PR description. If SPECS are present: make sure the implementation matches ALL the specs.
The specs override other instructions (code, inline comments in code, etc). ALL specs MUST be implemented.

Copy link
Copy Markdown
Member Author

@AlexandreYang AlexandreYang left a comment

Choose a reason for hiding this comment

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

Iteration 4 self-review — APPROVE (no new findings)

Reviewed commit 7242f5e which fixes the DNS family selection P1:

  • buildPinger now calls net.ResolveIPAddr(resolveNet, host) in the goroutine with correct family (ip4/ip6/ip)
  • execPing uses original host for PING header and statistics footer display
  • printStats takes host string parameter; stats.Addr (which would show the IP) is no longer used in display
  • net.IPAddr and net.ResolveIPAddr added to ping per-command allowlist and builtinAllowedSymbols

Security: No new imports beyond net (base package, not banned). DNS is still context-bounded via goroutine + select.

Correctness: Retry path passes pinger.IPAddr().String() (already an IP) → net.ResolveIPAddr returns immediately without DNS. No goroutine leak: buffered channel (capacity 1) ensures the goroutine always drains.

Overall: no findings.

@AlexandreYang
Copy link
Copy Markdown
Member Author

Iteration 50 self-review result: APPROVE — 0 findings. Code is ready to merge. All previously identified issues have been fixed; the two documented intentional limitations (isScopedIPLiteral naming, directed-broadcast spin-loop) have been accepted. gofmt clean, all tests pass.

@chatgpt-codex-connector
Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Can't wait for the next one!

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

Copy link
Copy Markdown
Member Author

@AlexandreYang AlexandreYang left a comment

Choose a reason for hiding this comment

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

Review Summary (iteration 51 — confirming APPROVE)

Reviewed the ping builtin implementation at commit 70963f3e. This is a fresh re-review confirming the prior APPROVE from iteration 50.

Overall assessment: safe to merge. No new issues found.

What was reviewed

  • builtins/ping/ping.go — full implementation (593 lines)
  • builtins/ping/ping_internal_test.go — white-box tests for helpers
  • builtins/ping/ping_test.go — integration/functional tests
  • builtins/ping/builtin_ping_pentest_test.go — security/DoS test vectors
  • builtins/ping/ping_fuzz_test.go — fuzz harnesses
  • tests/scenarios/cmd/ping/ — 25 scenario YAML files
  • allowedsymbols/symbols_builtins.go — allowed-import list updates
  • SHELL_FEATURES.md, LICENSE-3rdparty.csv, go.mod/go.sum

No findings

# Priority File Finding
No issues found

Positive observations

  • Sandbox integrity preserved: no os.Open, os.Stat, or filesystem access; network I/O goes through net.DefaultResolver and pro-bing, both of which are explicitly whitelisted.
  • Dangerous flags blocked at parse time: -f, -b, -s, -I, -p, -R are unregistered and rejected by pflag before any code runs.
  • Broadcast/multicast/unspecified blocked post-resolution: ip.IsUnspecified(), ip.IsMulticast(), and the ip4[3] == 255 check catch dangerous destinations regardless of how they were resolved (DNS or literal). The known limitation for non-standard subnet directed-broadcasts is documented in code and SHELL_FEATURES.md.
  • Hard 120 s ceiling: maxTotalTimeout caps total run time; context cancellation is propagated through DNS and RunWithContext; all duration/count inputs are clamped with warnings.
  • Integer/float overflow safety: parsePingDuration guards against NaN, Inf, and float64 → int64 overflow; negative values are explicitly rejected.
  • Privileged fallback is clean: buildPinger is called with the already-resolved numeric IP on retry, so no second DNS query and no zone-identifier loss for scoped IPv6 addresses.
  • Test coverage is thorough: white-box unit tests for every helper, pentest vectors for all dangerous flag classes, fuzz harnesses for both flags and hostnames, and 25 scenario YAML files covering flag validation, address rejection, and clamping warnings.
  • Documentation up to date: SHELL_FEATURES.md entry and package godoc accurately describe behavior, limitations, and platform requirements.

@AlexandreYang
Copy link
Copy Markdown
Member Author

@codex review this PR

Important: Read the SPECS section of the PR description. If SPECS are present: make sure the implementation matches ALL the specs.
The specs override other instructions (code, inline comments in code, etc). ALL specs MUST be implemented.

@AlexandreYang
Copy link
Copy Markdown
Member Author

Iteration 51 self-review result: APPROVE — 0 findings. Code is clean and ready to merge.

@chatgpt-codex-connector
Copy link
Copy Markdown

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

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

Copy link
Copy Markdown
Member Author

@AlexandreYang AlexandreYang left a comment

Choose a reason for hiding this comment

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

Review Summary (iteration 52)

This is a fresh review of the ping builtin at HEAD 70963f3e. The implementation, tests, and documentation were re-examined end-to-end against all review dimensions.

Overall assessment: safe to merge. APPROVE (submitted as COMMENT because self-review is not permitted on GitHub).

What was reviewed

  • builtins/ping/ping.go — full implementation
  • builtins/ping/ping_internal_test.go, ping_test.go, builtin_ping_pentest_test.go, ping_fuzz_test.go
  • All scenario YAML files under tests/scenarios/cmd/ping/
  • allowedsymbols/symbols_builtins.go ping entry
  • SHELL_FEATURES.md, go.mod/go.sum, LICENSE-3rdparty.csv

Security (A)

  • No direct filesystem access (os.Open, os.Stat, etc.) — ping only performs DNS and ICMP network I/O.
  • No os/exec, net/http, or unsafe imports.
  • Dangerous flags (-f, -b, -s, -I, -p, -R) are rejected by pflag at parse time (exit 1) before any network I/O.
  • Broadcast, multicast, and unspecified destinations are rejected in buildPinger before the pinger is created. The .255 heuristic for directed-broadcast and its known false-positive are both documented and intentional (do not re-flag).
  • Context propagation is correct: context.WithTimeout wraps the outer shell context; DNS resolution, socket creation, and ICMP sends all respect the deadline.
  • pro-bing.NewPinger is always called with a pre-resolved numeric IP, so the context-unaware internal net.ResolveIPAddr is a no-op (instant lookup, no goroutine leak).
  • The privileged socket retry path re-uses the already-resolved IP, so no second DNS round-trip can return a different address after the broadcast/multicast check.
  • isPermissionErr cannot be tricked by DNS errors because DNS errors are caught and returned by buildPinger before RunWithContext is ever called.
  • maxTotalTimeout (120 s) provides a hard cap bounding any spin-loop risk from the pro-bing directed-broadcast retry bug on non-standard subnets (documented and intentional — do not re-flag).
  • gofmt -l reports no violations. go vet ./builtins/ping/... is clean.
  • Allowed-symbols list accurately describes all imports.

Bash Compatibility / Correctness (B, C)

  • All ping scenarios are correctly marked skip_assert_against_bash: true.
  • Duration parsing: Go literals and plain integer/float seconds both accepted; negative, NaN, Inf, and overflow values are all rejected.
  • Clamp warnings are emitted to stderr before DNS/ICMP. Exit codes are correct. Statistics are printed unconditionally. icmp_seq is offset by +1 (POSIX convention).

Test Coverage (D)

  • Scenario tests cover all flag rejection, address rejection, clamp-warning, and format/help cases.
  • Go unit tests cover all unexported helpers.
  • Pentest tests cover all attack vectors from the checklist.
  • Fuzz tests cover flag parsing and hostname inputs.
  • Network-dependent tests are gated behind RSHELL_NET_TEST=1.

Documentation (E)

  • SHELL_FEATURES.md entry is accurate and complete. Package-level doc comment documents all flags, exit codes, and output format. LICENSE-3rdparty.csv updated.

No findings.

# Priority File Finding
No findings

@AlexandreYang
Copy link
Copy Markdown
Member Author

@codex review this PR

Important: Read the SPECS section of the PR description. If SPECS are present: make sure the implementation matches ALL the specs.
The specs override other instructions (code, inline comments in code, etc). ALL specs MUST be implemented.

@AlexandreYang
Copy link
Copy Markdown
Member Author

Iteration 52 self-review result: APPROVE — 0 findings. Code confirmed clean (3rd consecutive APPROVE).

@chatgpt-codex-connector
Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Already looking forward to the next diff.

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

Copy link
Copy Markdown
Member Author

@AlexandreYang AlexandreYang left a comment

Choose a reason for hiding this comment

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

Code Review — feat(ping): implement ping builtin (iteration 53)

Overview

This PR implements a ping builtin using github.com/prometheus-community/pro-bing v0.8.0. Reviewed the full diff including builtins/ping/ping.go, all test files, scenario YAMLs, allowedsymbols/symbols_builtins.go, SHELL_FEATURES.md, LICENSE-3rdparty.csv, and CI workflow changes.

The three commits since the last APPROVE (iterations 50–52) are minor cleanups:

  1. isScopedIPLiteral symbols (net.ParseIP, strings.IndexByte) added to both the per-command "ping" entry and the global builtinAllowedSymbols list.
  2. maxTotalTimeout = 120 * time.Second named constant extracted (eliminates magic number).
  3. Warning message derives the cap value from maxTotalTimeout.Seconds() instead of a hardcoded "120s" string literal.

No new code logic was introduced. All changes are formatting/style/correctness improvements.

Assessment: safe to merge

Findings

None. No P0–P3 findings.

Security

  • No filesystem access (os.Open, os.Stat, etc.) — all I/O is ICMP/DNS, which is the explicit purpose of this builtin.
  • Dangerous flags (-f, -b, -s, -I, -p, -R) rejected at flag-parse time before any network I/O.
  • Broadcast (last-octet .255), multicast, and unspecified destinations rejected in buildPinger before passing to pro-bing.
  • Context cancellation propagates into both DNS resolution (LookupIPAddr / LookupIP) and pinger.RunWithContext.
  • Hard 120 s cap (maxTotalTimeout) bounds worst-case wall-clock time even if all per-flag values are maxed.
  • No os/exec, unsafe, or net/http imports. All new symbols are on the allowlist.
  • isScopedIPLiteral correctly strips the %zone suffix before calling net.ParseIP — no injection surface.

Test Coverage

All code paths covered:

  • 33 scenario YAML files covering blocked flags, address rejection, flag validation, clamping warnings, and help output — all marked skip_assert_against_bash: true (intentional divergence).
  • Go unit tests (ping_test.go, ping_internal_test.go) cover internal helpers, flag acceptance, context cancellation, and network tests (gated on RSHELL_NET_TEST=1).
  • Pentest tests (builtin_ping_pentest_test.go) exercise integer overflow, long hostnames, injection attempts, and context deadline safety.
  • Two fuzz targets (FuzzPingFlags, FuzzPingHostname) with boundary-value seed corpora; CI fuzz job passes.

Known Intentional Limitations (previously accepted)

  1. isScopedIPLiteral handles IPv4+zone and IPv6+zone (documented in code comments).
  2. Directed-broadcast spin-loop for non-standard subnets (e.g. /25) is bounded by maxTotalTimeout; documented in buildPinger comment and SHELL_FEATURES.md.

CI

All 30 CI checks pass on the current HEAD (70963f3e).

@AlexandreYang
Copy link
Copy Markdown
Member Author

@codex review this PR

Important: Read the SPECS section of the PR description. If SPECS are present: make sure the implementation matches ALL the specs.
The specs override other instructions (code, inline comments in code, etc). ALL specs MUST be implemented.

@AlexandreYang
Copy link
Copy Markdown
Member Author

dummy

@chatgpt-codex-connector
Copy link
Copy Markdown

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

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

Copy link
Copy Markdown
Member Author

@AlexandreYang AlexandreYang left a comment

Choose a reason for hiding this comment

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

Review Summary

Reviewed the ping builtin implementation (PR #118, commit 70963f3).

Overall assessment: safe to merge.

No findings. This is a thorough, well-structured implementation.


Security

  • No filesystem access bypasses — all output uses callCtx.Outf/Errf; no os.Open, os.Stat, or raw file access added.
  • All six dangerous flags (-f, -b, -s, -I, -p, -R) are rejected at flag-parse time by pflag; there is no code path that could accidentally enable them.
  • Broadcast (.255 heuristic), multicast (ip.IsMulticast()), and unspecified (ip.IsUnspecified()) destinations are all rejected before probing.NewPinger is called, preventing the pro-bing v0.8.0 auto-SO_BROADCAST retry from sending broadcast traffic.
  • DNS resolution is context-aware (net.DefaultResolver.LookupIPAddr / LookupIP with the caller's context), avoiding goroutine leaks on cancellation.
  • On the privileged retry path, the already-resolved numeric IP is passed to buildPinger, so probing.NewPinger calls net.ResolveIPAddr synchronously with no network round-trip and no context-cancellation gap.
  • Import allowlist additions are all appropriate: net.DefaultResolver and the five pro-bing symbols serve the explicit purpose of the builtin. No os/exec, unsafe, or net/http.
  • The two known intentional limitations (directed-broadcast spin-loop on non-standard subnets bounded by maxTotalTimeout; isScopedIPLiteral handling IPv4+zone and IPv6+zone) are both correctly documented and were pre-flagged in the review spec.

Correctness

  • Duration parsing: overflow guard (maxDurationSec), NaN/Inf rejection, and negative-value rejection are all present and tested.
  • clampInt / clampDuration are correct and fully unit-tested.
  • Context cancellation propagates from the outer shell context into both the DNS lookup and pinger.RunWithContext.
  • The pinger = p2 reassignment on privileged retry ensures pinger.Statistics() reflects packets sent by the second pinger, not the first (which sent zero).
  • Statistics are printed unconditionally — including on error and context-cancellation — matching POSIX ping behavior.
  • Exit code semantics: 0 iff at least one reply received, 1 otherwise; matches POSIX.

Test Coverage

Adequate. Every code path is covered:

Code path Coverage
All dangerous flags rejected Scenario YAML + pentest Go tests
Broadcast / multicast / unspecified rejection Scenario YAML
Duration parsing (Go literal, integer, float, overflow, NaN, Inf, negative) ping_internal_test.go
clamp warnings (-c, -W, -i) Scenario YAML
Total-time cap warning Scenario YAML
Help flag Scenario YAML + Go test
Missing / extra host args Scenario YAML + Go test
Context cancellation Go test (pentest + functional)
Fuzz: flags + hostnames ping_fuzz_test.go
isPermissionErr (EPERM/EACCES/EPROTONOSUPPORT/string fallback) ping_internal_test.go

All scenario tests correctly carry skip_assert_against_bash: true.

Positive Observations

  • The two-attempt (unprivileged → privileged) fallback is clean and well-commented.
  • The isScopedIPLiteral helper correctly handles the zone-separator case that net.ParseIP rejects.
  • The broadcast heuristic false-positive is explicitly documented in code, a test scenario, and SHELL_FEATURES.md.
  • Fuzz targets cover both the flag-parsing and hostname-resolution surfaces with carefully chosen seed corpora.
  • SHELL_FEATURES.md and the Description field are both updated.

@AlexandreYang
Copy link
Copy Markdown
Member Author

@codex review this PR

Important: Read the SPECS section of the PR description. If SPECS are present: make sure the implementation matches ALL the specs.
The specs override other instructions (code, inline comments in code, etc). ALL specs MUST be implemented.

Copy link
Copy Markdown

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

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: 70963f3ef0

ℹ️ 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 builtins/ping/ping.go
Comment on lines +409 to +410
if ip4 := ip.To4(); ip4 != nil && ip4[3] == 255 {
return nil, fmt.Errorf("broadcast destination not allowed: %s", ip)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Block non-.255 directed broadcast addresses

The broadcast guard only rejects IPv4 destinations whose last octet is 255, so directed broadcasts on non-/24-style masks (for example a /25 broadcast like 192.168.1.127) are still treated as valid and can be sent. In those environments this defeats the stated safety guarantee that broadcast destinations are rejected before transmission, and with pro-bing’s Linux EACCES retry path it can still generate broadcast ICMP traffic instead of failing fast.

Useful? React with 👍 / 👎.

@AlexandreYang
Copy link
Copy Markdown
Member Author

/merge

@gh-worker-devflow-routing-ef8351
Copy link
Copy Markdown

gh-worker-devflow-routing-ef8351 bot commented Mar 18, 2026

View all feedbacks in Devflow UI.

2026-03-18 16:05:15 UTC ℹ️ Start processing command /merge


2026-03-18 16:05:20 UTC ℹ️ MergeQueue: pull request added to the queue

The expected merge time in main is approximately 1m (p90).


2026-03-18 16:05:32 UTC 🚨 MergeQueue: This merge request is in error because of DDCI

DDCI response: DDCI is currently blocked for this repository. Please reach out in #ci-infra-support for additional information.

Copy link
Copy Markdown
Member Author

@AlexandreYang AlexandreYang left a comment

Choose a reason for hiding this comment

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

Review Summary

Scope: PR #118ping builtin implementation (builtins/ping/ping.go, tests, scenarios, allowedsymbols, SHELL_FEATURES.md, go.mod/go.sum, LICENSE-3rdparty.csv, CI fuzz config).

Overall assessment: safe to merge. No findings (APPROVE intent — blocked from self-approving).

This is iteration 55; the two previously documented limitations are intentional and correctly excluded per the review brief:

  1. isScopedIPLiteral handling IPv4+zone and IPv6+zone — documented in function comment.
  2. Directed-broadcast spin-loop for non-standard subnets — bounded by maxTotalTimeout, documented in buildPinger.

Security

  • No direct filesystem access (os.Open/os.Stat/etc.) — sandbox invariant maintained.
  • The one context-free probing.NewPinger call receives only a pre-resolved numeric IP, making the synchronous net.ResolveIPAddr inside it instantaneous with no goroutine leak.
  • Destination filtering (unspecified, multicast, last-octet-255) is applied before any ICMP socket is opened.
  • isPermissionErr string matching is case-insensitive and covers known Unix and Windows variants.
  • Hard 120 s wall-clock cap via context.WithTimeout enforced before RunWithContext.
  • No unsafe, os/exec, or net/http imports; import allowlist in symbols_builtins.go is correct and complete.

Correctness

  • parsePingDuration overflow guard is correct: maxDurationSec is computed as integer division before float64 conversion, avoiding off-by-one in the overflow boundary.
  • p.Timeout (pro-bing internal) and total (context deadline) are consistent: total adds pingGracePeriod on top of the pro-bing timeout, giving the last packet's reply a window to arrive.
  • Statistics are printed unconditionally, mirroring POSIX behaviour on SIGINT/timeout.
  • err != nil && ctx.Err() == nil correctly suppresses the redundant error log on context cancellation.

Test Coverage

  • Comprehensive: unit tests for all helpers (clampInt, clampDuration, parsePingDuration, durToMS, isPermissionErr, isScopedIPLiteral), pentest tests for all blocked flags and boundary inputs, fuzz tests for flags and hostnames, scenario tests for all error paths and flag clamping. Network-dependent tests are gated behind RSHELL_NET_TEST=1.

Positive Observations

  • Context-aware DNS resolution avoids goroutine leaks on cancellation.
  • Pro-bing NoopLogger prevents internal library noise from leaking to the user.
  • All scenario tests correctly carry skip_assert_against_bash: true.
  • SHELL_FEATURES.md, allowedsymbols, LICENSE-3rdparty.csv, and go.mod/go.sum are all consistently updated.

# Priority File Finding
No findings

Merged via the queue into main with commit d6f70d7 Mar 18, 2026
35 of 36 checks passed
@AlexandreYang AlexandreYang deleted the alex/ping-v4 branch March 18, 2026 16:07
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