## Why
Memory read telemetry currently reconstructs the executable shell
command after a tool call finishes. That duplicates shell, login-policy,
and cwd resolution owned by the tool handlers, and can diverge from the
environment-specific command that unified exec actually ran.
## What changed
- Expose the existing restricted shell-script parser directly for raw
script text.
- Parse `shell_command` and `exec_command` input into plain command argv
before classifying memory reads.
- Preserve all-or-nothing safe-command validation for multi-command
scripts.
- Remove cwd resolution, shell selection, and the unnecessary async
boundary from memory read metric emission.
## Testing
- `just test -p codex-shell-command`
- `cargo check -p codex-core`
## Why
Shell detection needs to be available through the `Environment`
abstraction so callers can ask the selected local or remote environment
for shell metadata without adding a separate HTTP endpoint or parallel
info-source path. This keeps shell metadata shaped like the existing
environment-owned filesystem capability and lets remote environments
answer through exec-server JSON-RPC.
## What changed
- Added `environment/info` to the exec-server protocol/client/server and
exposed `Environment::info()`.
- Added local and remote environment info providers on `Environment`,
following the existing capability-provider pattern used for filesystem
access.
- Moved the shared shell detection logic into `codex-shell-command` and
kept core shell APIs as wrappers around that implementation.
- Returned shell metadata as `EnvironmentInfo { shell: ShellInfo }`
using the existing shell detection path.
- Added a remote environment test that calls `Environment::info()`
through an exec-server-backed environment.
## Validation
- `git diff --check`
- `just test -p codex-shell-command`
- `just test -p codex-core -E 'test(/shell::tests::/)'`\n- `just test -p
codex-exec-server environment`
## Summary
Fixes a regression introduced in #10941 so that heredocs do not permit
file redirects to be approved by rules, and adds scenario tests to cover
this behavior.
Previously, heredoc command parsing would allow redirects and
environment variables:
```bash
# commands_for_exec_policy() would parse this via parse_shell_lc_single_command_prefix
PATH=/tmp/bad:$PATH cat <<'EOF' > /tmp/bad/hello.txt
hello
EOF
```
This conflicts with the Codex Rules documentation; heredoc parsing logic
should abide by the same strictness of parsing.
## Tests
- [x] Updated unit tests accordingly
- [x] Added scenario tests for these cases
---------
Co-authored-by: Codex <noreply@openai.com>
## Summary
Fixes a few things in our exec_policy handling of prefix_rules:
1. Correctly match redirects specifically for exec_policy parsing. i.e.
if you have `prefix_rule(["echo"], decision="allow")` then `echo hello >
output.txt` should match - this should fix#10321
2. If there already exists any rule that would match our prefix rule
(not just a prompt), then drop it, since it won't do anything.
## Testing
- [x] Updated unit tests, added approvals ScenarioSpecs
## Summary
This should rarely, if ever, happen in practice. But regardless, we
should never provide an empty list of `commands` to ExecPolicy. This PR
is almost entirely adding test around these cases.
## Testing
- [x] Adds a bunch of unit tests for this