`/status` prints the global AGENTS.md in full while the Directory row above it collapses to `~`

Resolved 💬 0 comments Opened Aug 23, 2026 by snowyukitty Closed Aug 25, 2026

The /status card renders Directory collapsed to ~, and Agents.md, two
rows below it, in full. A global AGENTS.md lives under the home directory by
default, so that row prints the home directory and with it the local username.

Three rows of the card, before and after the one-line change below:

  before
  Directory:        ~\work\myproject
  Permissions:      Custom (workspace with network access, Ask for approval)
  Agents.md:        C:\Users\alice\.codex\AGENTS.md, AGENTS.md

  after
  Agents.md:        ~\.codex\AGENTS.md, AGENTS.md

<details>
<summary>The full card these rows come from</summary>

  Rendered by driving new_status_output_with_rate_limits_handle from a
  throwaway test on 479c8c8924, not captured from a live session. The
  workspace is ~/work/myproject and the global AGENTS.md is under ~/.codex.
  The only edit is the username, replaced with alice.

╭─────────────────────────────────────────────────────────────────────────────╮
│  >_ OpenAI Codex (v0.0.0)                                                   │
│                                                                             │
│ Visit https://chatgpt.com/codex/settings/usage for up-to-date               │
│ information on rate limits and credits                                      │
│                                                                             │
│  Model:            gpt-5.1-codex-max (reasoning none, summaries auto)       │
│  Directory:        ~\work\myproject                                         │
│  Permissions:      Custom (workspace with network access, Ask for approval) │
│  Agents.md:        C:\Users\alice\.codex\AGENTS.md, AGENTS.md               │
│                                                                             │
│  Token usage:      1.2K total  (800 input + 400 output)                     │
│  Context window:   100% left (1.2K used / 272K)                             │
│  Limits:           data not available yet                                   │
╰─────────────────────────────────────────────────────────────────────────────╯

</details>

The capture is from Windows, but nothing about it is Windows specific: the same
mismatch appears wherever the global AGENTS.md resolves inside the home
directory. Of the 20 status snapshots that render an Agents.md row, all 20
render <none>, so none of them exercises this.

Where

status/card.rs renders Directory with format_directory_display, which
collapses through relativize_to_home (exec_command.rs).
compose_agents_summary (status/helpers.rs) ends instead at
normalize_agents_display_path, which is only dunce::simplified(path).

To be precise about which paths land there, since the loop has several arms: a
source whose parent is the cwd prints as a bare filename, a source whose parent
is an ancestor of the cwd prints as ../…, and a source under the cwd prints
relative to it. A source that is none of those - which a global AGENTS.md
outside the workspace is - reaches normalize_agents_display_path and prints
absolute.

Existing coverage for this is platform-dependent

compose_agents_summary_includes_global_agents_path,
compose_agents_summary_names_global_agents_override and
compose_agents_summary_orders_global_before_project_agents each compare
compose_agents_summary against format_directory_display for the global
path, so the equality is already written down.

All three build the fixture in a TempDir, which ties what they check to where
the system temp directory happens to live. On Windows it lives under
%USERPROFILE%, and there all three fail today (username redacted):

Diff < left / right :
< C:\Users\<user>\AppData\Local\Temp\.tmp9Hn0tM\global.md
> ~\AppData\Local\Temp\.tmp9Hn0tM\global.md

Where the temp directory is not under the home directory, both sides return the
same raw path and the comparison holds without reaching the collapse. I have
only measured this on Windows; the Linux and macOS reading is inference from
where /tmp sits, not something I ran.

Fix

One commit on 479c8c8924. The behaviour change is one line:

 fn normalize_agents_display_path(path: &Path) -> String {
-    dunce::simplified(path).display().to_string()
+    format_directory_display(dunce::simplified(path), /*max_width*/ None)
 }

so each instruction source gets the same rule the Directory row already uses.
That cuts both ways on purpose: a source under the home directory collapses, and
a source outside it still prints in full even when the workspace itself
collapses.

Nothing else moves. relativize_to_home returns None for a non-absolute path,
so the cwd-relative arm renders byte-identically, and so does an absolute path
that is not under the home directory. dunce::simplified has to stay ahead of
the collapse - dirs::home_dir returns a non-verbatim path, so strip_prefix
would miss on a \?\-prefixed one.

The commit also adds a test that builds the path under the home directory
directly instead of in a TempDir, so the collapse is checked wherever the
suite runs, and skips when no home directory resolves, since relativize_to_home
cannot collapse anything in that case either.

c9fefb7453 is the version I am proposing and I will keep that sha reachable.
If you would rather have it on a newer base, I will push a new commit and update
this link rather than move the old one.

The TODO next to it

There is a TODO(anp) above that loop about rationalizing instruction-source
summaries with the TUI's broader foreign-path display strategy. On control flow
this change stays clear of it - foreign sources return earlier through
inferred_native_path_string, and the fallback here is reached only by native
paths that already resolved to an absolute path - but I do not want to overstate
that as settling the question. The fair objection is that a card can now show a
collapsed native source and a fully-printed foreign source on the same line,
which is part of what that TODO exists to resolve wholesale. If you would rather
the whole surface move at once, this is small enough to fold into that work.

Validation

RUST_MIN_STACK=16777216 cargo test -p codex-tui --lib on Windows, both
measured on 479c8c8924:

  • before: 3737 passed, 3 failed, 6 ignored - the three cases above
  • after: 3741 passed, 0 failed, 6 ignored - those three, plus the new test

cargo clippy -p codex-tui --all-targets --all-features -- -D warnings is
clean. I have not run the suite on Linux or macOS.

Environment

Built from source at 479c8c8924, not a release build; Windows 11 26200,
x86_64-pc-windows-msvc. The rendering mismatch does not depend on the
terminal; only the three failing tests are Windows-visible.

I have not been able to open a pull request here from a fork - if that is wrong
and there is a path I have missed, say so and I will open one. Otherwise the
commit is there to cherry-pick, and I am happy to reshape it however suits you.

View original on GitHub ↗