Skip to content

feat(builtins): add free builtin for host memory pressure verification#555

Merged
matt-dz merged 5 commits into
mainfrom
louis-cqrl/free-builtin
Jul 21, 2026
Merged

feat(builtins): add free builtin for host memory pressure verification#555
matt-dz merged 5 commits into
mainfrom
louis-cqrl/free-builtin

Conversation

@louis-cqrl

Copy link
Copy Markdown
Contributor

What does this PR do?

Adds a free builtin that reports host memory and swap usage (total/used/free/shared/buff-cache/available), scoped to free and free -h per the accepted-candidate design brief. Backed by a new builtins/internal/meminfo package that reads /proc/meminfo on Linux, bypassing AllowedPaths the same way ss/ip route/df already do (hardcoded kernel pseudo-file path, never derived from user input). macOS and Windows intentionally return "not supported" rather than a partial implementation — neither exposes the buffers/cache/shared breakdown through a syscall this shell can call without cgo, and reporting those columns as a literal 0 would misrepresent "not available" as "none."

Motivation

Item from the rshell command roadmap: "Host-level memory pressure verification" (free), listed as "no gate needed." Per the design brief on origin/alex/rshell_cmds_triage:candidates.md, this is the first-pass host-memory snapshot used at the start and end of memory-leak investigations, complementing ps (per-process memory) and the planned vmstat (pressure trends over repeated samples — explicitly out of scope for free).

Researched past PR review comments on df/ss/ip route/ps/logrotate before implementing, to avoid repeating prior mistakes (sandbox-bypass documentation gaps, integer overflow in derived columns, pflag explicit-value handling, help-flag correctness, Windows struct-offset bugs). See AGENTS.md's Security Design Decisions and Testing sections for the free-specific entries this PR adds.

Testing

  • builtins/internal/meminfo/meminfo_linux_test.go: fixture-based parser tests (happy path, MemAvailable fallback for pre-3.14 kernels, malformed/unitless line skipping, overflow, context cancellation, oversized-line handling).
  • builtins/free/free_internal_test.go: humanBytes (including exact round-half-to-even decimal ties), writeOutput (including the cgroup-underflow fallback branch for the used column).
  • builtins/free/free_test.go: help/error paths (cross-platform), plus runtime.GOOS-gated happy-path/not-supported checks.
  • tests/scenarios/cmd/free/: help + error-path scenarios (skip_assert_against_bash: truefree ships in procps-ng, not installed in the debian:bookworm-slim comparison image).
  • Self-reviewed via the code-review skill + codex exec review in parallel; one real bug found and fixed (custom rounding in -h diverged from free's actual round-half-to-even at exact ties) and one Codex finding investigated and rejected as factually incorrect (see commit 41ee6d63).
  • go build/go vet/go test ./... clean on darwin; cross-compiled and vetted clean for linux/amd64 and windows/amd64. Could not exercise the Linux happy path against a live container in this environment (Docker Desktop here requires an org sign-in) — worth a sanity check on a real Linux box or in CI.

Checklist

  • Tests added/updated
  • Documentation updated (README.md, SHELL_FEATURES.md, AGENTS.md)

Reports total/used/free/shared/buff-cache/available memory and swap
usage via /proc/meminfo on Linux (free, free -h only, per the accepted
candidate scope). macOS and Windows report "not supported" rather than
a partial breakdown, since neither exposes buffers/cache/shared through
a syscall this shell can call without cgo.
humanBytes pre-rounded with a custom round-half-away-from-zero helper,
which silently diverges from procps-ng's plain printf("%.1f") at exact
decimal ties (e.g. 1310720 bytes is exactly 1.25Mi: old code printed
1.3Mi, real free prints 1.2Mi). Format directly with fmt.Sprintf
instead, which applies the same round-half-to-even Go and C share.

Also drops a doc comment referencing a meminfo_windows.go that was
never added, and adds direct unit tests for writeOutput's derived
columns (used-memory underflow fallback, swap row, human mode), which
were previously only reachable via the Linux-gated integration test.
@datadog-prod-us1-3

This comment has been minimized.

@louis-cqrl

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

To use Codex here, create a Codex account and connect to github.

@louis-cqrl

Copy link
Copy Markdown
Contributor Author

@codex 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: 41ee6d63ce

ℹ️ 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/free/free.go Outdated
Comment thread builtins/free/free.go Outdated
used now follows GNU free's actual MemTotal-MemAvailable formula instead
of the naive Total-Free-BuffCache subtraction, which under-reports used
memory under cgroup/container accounting. Human-readable values >= 10
now truncate instead of round, matching procps-ng's scale_size (e.g.
65.926 GiB prints "65Gi", not "66Gi").
@louis-cqrl

Copy link
Copy Markdown
Contributor Author

@codex 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: 3781d64134

ℹ️ 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/free/free.go Outdated
Truncating human-readable sizes >= 10 with math.Trunc + strconv.FormatFloat
fails the builtin symbol allowlist check (analysis/symbols_builtins.go).
Use a uint64 conversion (also truncates toward zero, val is always in
[10, 1024)) with the already-allowlisted strconv.FormatUint instead.
@louis-cqrl

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

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

Reviewed commit: dc56edae91

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

@louis-cqrl
louis-cqrl marked this pull request as ready for review July 17, 2026 20:08
@matt-dz matt-dz added the verified/analysis Human-reviewed static analysis changes label Jul 21, 2026
@matt-dz
matt-dz added this pull request to the merge queue Jul 21, 2026
Merged via the queue into main with commit 08e86e6 Jul 21, 2026
41 of 42 checks passed
@matt-dz
matt-dz deleted the louis-cqrl/free-builtin branch July 21, 2026 15:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

verified/analysis Human-reviewed static analysis changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants