feat(help): list configured AllowedPaths in help output#248
Conversation
Show the active sandbox roots in `help`, with an explicit notice when none are configured so operators can tell that state apart from "all filesystem access allowed".
|
@codex review this PR Please use the following severity format for all findings:
Prefix each finding title with its priority label, e.g. "P0: ...", "P1: ...", etc. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 153bb55ac1
ℹ️ 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
left a comment
There was a problem hiding this comment.
Self-Review (iteration 1)
Reviewed PR #248 — adds an Allowed paths: section to the help builtin output, wires a new CallContext.AllowedPathsList accessor backed by Sandbox.Paths(), and adds Go + scenario coverage.
Overall assessment: safe to merge with minor doc/wording polish. No P0/P1 findings.
Findings summary
Coverage
| Code path | Scenario test | Go test | Status |
|---|---|---|---|
| Configured paths render | tests/scenarios/cmd/help/allowed_paths.yaml |
help_test.go:411 |
Covered |
| Multiple paths line-per-line | — | help_test.go:421 |
Covered |
| Empty AllowedPaths notice | tests/scenarios/cmd/help/no_allowed_paths.yaml |
help_test.go:432 |
Covered |
r.sandbox == nil branch in accessors |
— | — | Implicit (same observable behavior as empty list) |
Positive observations
- Nil-safe accessors in both CallContext constructions in
runner_exec.go— defensive againstr.sandbox == nil. printAllowedPathsearly-returns whencallCtx.AllowedPathsListitself is nil — backward-compatible with any caller that builds a CallContext without wiring the new accessor.- Empty-state messaging follows the precedent set by the existing "All commands are allowed in this session" line.
skip_assert_against_bash: trueis correctly set on both new scenario YAMLs (bash has no AllowedPaths concept).
|
Iteration 1 self-review result
|
- SHELL_FEATURES.md / README.md: mention the new "Allowed paths" section
in the help output and the empty-state notice (project rule requires
docs to stay in sync).
- builtins/help/help.go: refine empty-state wording from "all filesystem
access blocked" to "no filesystem paths are reachable" since `ss`,
`ip route`, `df`, and `ps` intentionally bypass AllowedPaths for
kernel-state reads; expand the function and package doc comments.
- tests/scenarios/cmd/help/{allowed_paths,no_allowed_paths}.yaml: use
required `|+` block scalar for `expect.stderr` per AGENTS.md.
- builtins/tests/help/help_test.go: update assertion to new wording.
|
@codex review this PR Please use the following severity format for all findings:
Prefix each finding title with its priority label, e.g. "P0: ...", "P1: ...", etc. |
AlexandreYang
left a comment
There was a problem hiding this comment.
Self-Review (iteration 2)
Reviewed the cumulative PR diff at HEAD 39cc4470. All iteration-1 findings have been addressed:
- P2 docs —
SHELL_FEATURES.mdandREADME.mdnow document theAllowed paths:section and empty-state notice. ✓ - P3 empty-state wording — refined to "no filesystem paths are reachable" and the function comment now calls out the
ss/ip route/df/pskernel-state bypasses. ✓ - P3 package docstring — overview now includes the new section. ✓
- P3 (Codex) YAML block scalars — both scenario YAMLs use the required
|+form forexpect.stderr. ✓
Overall assessment: safe to merge. No P0/P1/P2/P3 findings in this iteration.
Findings summary
None — clean iteration.
Coverage
| Code path | Scenario test | Go test | Status |
|---|---|---|---|
| Configured paths render | tests/scenarios/cmd/help/allowed_paths.yaml |
help_test.go:411 |
Covered |
| Multiple paths line-per-line | — | help_test.go:421 |
Covered |
| Empty AllowedPaths notice | tests/scenarios/cmd/help/no_allowed_paths.yaml |
help_test.go:432 |
Covered |
r.sandbox == nil branch |
— | — | Implicit (observably identical to empty list) |
Docs strings in SHELL_FEATURES.md / README.md |
n/a (prose) | n/a | Updated |
Verification
make fmt✓go build ./...✓go test ./builtins/tests/help/...✓go test ./tests/ -run TestShellScenarios✓
|
Iteration 2 self-review result
|
|
@codex review this PR Please use the following severity format for all findings:
Prefix each finding title with its priority label, e.g. "P0: ...", "P1: ...", etc. |
AlexandreYang
left a comment
There was a problem hiding this comment.
Self-Review (iteration 3)
HEAD unchanged from iteration 2 (39cc4470). Re-confirmed all dimensions on the cumulative diff:
- Security — no new file access;
Sandbox.Paths()returns strings already exposed via$ALLOWED_PATHS. Nil-safe accessors. No injection, TOCTOU, or DoS surface introduced. - Bash compatibility — both new scenario YAMLs carry
skip_assert_against_bash: true(correct; bash has no AllowedPaths concept). - Correctness —
len(paths) == 0empty-state branch handles bothr.sandbox == nilandSandbox{roots: []}. - Coverage — adequate (3 Go tests + 2 scenarios).
- Code quality — naming consistent with existing
printFeatureTable/printUnsupportedSummarysiblings. - Platform — output is plain strings;
filepath.Absalready produces OS-native paths in the sandbox layer.
Overall assessment: safe to merge. No P0/P1/P2/P3 findings.
Findings summary
None — clean iteration.
|
Iteration 3 self-review result — P0:0 P1:0 P2:0 P3:0. |
|
@codex review this PR Please use the following severity format for all findings:
Prefix each finding title with its priority label, e.g. "P0: ...", "P1: ...", etc. |
AlexandreYang
left a comment
There was a problem hiding this comment.
Self-Review (iteration 4)
HEAD unchanged from iteration 3 (39cc4470). Re-confirmed all dimensions:
- Security, bash compat, correctness, coverage, code quality, platform — all clean.
Overall assessment: safe to merge. No P0/P1/P2/P3 findings.
None — clean iteration.
|
Iteration 4 self-review result — P0:0 P1:0 P2:0 P3:0. |
|
@codex review this PR Please use the following severity format for all findings:
Prefix each finding title with its priority label, e.g. "P0: ...", "P1: ...", etc. |
AlexandreYang
left a comment
There was a problem hiding this comment.
Self-Review (iteration 5)
HEAD unchanged from iteration 4 (39cc4470). Re-confirmed all dimensions across the cumulative diff:
- Security: no new fs access, nil-safe accessors, no escape surface
- Bash compat: scenarios correctly
skip_assert_against_bash: true - Correctness: empty/nil paths both handled
- Coverage: 3 Go tests + 2 scenarios cover all new code paths
- Code quality: helper naming and call-site placement match siblings
- Platform: filepath-native paths
Overall assessment: safe to merge. No P0/P1/P2/P3 findings.
None — clean iteration.
|
Iteration 5 self-review result — P0:0 P1:0 P2:0 P3:0. |
|
@codex review this PR Please use the following severity format for all findings:
Prefix each finding title with its priority label, e.g. "P0: ...", "P1: ...", etc. |
AlexandreYang
left a comment
There was a problem hiding this comment.
Self-Review (iteration 6)
HEAD unchanged from iteration 5 (39cc4470). Cumulative diff re-confirmed clean across security, bash compatibility, correctness, coverage, code quality, and platform compatibility.
Overall assessment: safe to merge. No P0/P1/P2/P3 findings.
None — clean iteration.
|
Iteration 6 self-review result — P0:0 P1:0 P2:0 P3:0. |
Review-Fix Loop Summary
Iteration log
Final state
Remaining issuesNone. |
|
Codex Review: Didn't find any major issues. Delightful! ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
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". |
Summary
Allowed paths:section to the defaulthelpoutput that lists the configured sandbox roots, one per line.(no allowed paths configured — all filesystem access blocked)so the empty state is unambiguous (perinterp/api.gosemantics, an empty AllowedPaths blocks all filesystem access — it is not "unrestricted").Sandbox.Paths()to builtins via a newCallContext.AllowedPathsListaccessor, wired in bothrunner_exec.goCallContextconstructions.Test plan
go build ./...make fmtgo test ./builtins/tests/help/...— including three new tests covering single path, multiple paths line-per-line, and the empty-state notice.go test ./tests/ -run TestShellScenarios— including two new scenarios (allowed_paths.yaml,no_allowed_paths.yaml).rshell --allow-all-commands [-p /tmp,/var/log] -c help.