Repository navigation
fix(pstack): escalate project-skill writes under Codex's read-only .agents - #31
Merged
Merged
Conversation
…gents Codex's workspace-write sandbox keeps a repo's .agents/ read-only, so a skill that writes a project-local skill there failed its mkdir, and the agent fell back to upstream's .cursor/skills/, where Codex never looks. pstack-harness now says to run those writes with require_escalated from the first attempt, and to stop rather than write elsewhere when denied. The smoke test could not exercise that, because codex exec had no way to answer an escalation request unless the user's config.toml happened to set an approvals reviewer. Codex runs now pass --approve-for-me. The why scenario's task now says the synthesizer still runs, since "run only the source control investigator" read as skipping it. The test also removes the trust entries each codex exec adds to ~/.codex/config.toml.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
The first Codex smoke run on a fresh Codex 0.163.0 install passed 8 of 10 scenarios. The two failures came from gaps in the port, not from upstream's skills:
create-verification-skillwrote its skill where Codex can't find it. Codex'sworkspace-writesandbox keeps a repo's.agents/and.codex/read-only, while.claude/and.cursor/stay writable.mkdir -p .agents/skills/verify-usersfailed withRead-only file system. The agent fell back to upstream's.cursor/skills/verify-usersand linked.claude/skillsto it, and Codex never reads that folder. A real Codex session hits the same wall, becausepstack-harnesssays where project skills go but not that Codex blocks writing there.whyskipped its synthesizer. The task said "run only the source control investigator". The agent read "only" as covering Step 4 too, and wrote the report itself.Two more problems in the smoke test turned up along the way:
smoke.pyrancodex exec -s workspace-writewith no way to answer an escalation request. Escalation only worked if the user'sconfig.tomlset an approvals reviewer, which the port README assumes, and a fresh install doesn't. Foreign seats need escalation too, forclaude -p.codex execinto a repo adds a[projects."<repo>"] trust_level = "trusted"entry to~/.codex/config.toml. Deleting a run left its entry behind, and two runs left 21 of them.What changes
pstack-harness: a new path rule for Codex. Run shell commands that write under a repo's.agents/,~/.agents/, or~/.claude/withsandbox_permissions: "require_escalated"and a justification from the first attempt. If the write is denied, stop and tell the user. Never fall back to a folder like.cursor/skills/.foreign seatsalready has the same escalate-first rule forclaude.smoke.py:run_codexpasses--approve-for-mein place of-s workspace-write. That flag impliesworkspace-write, andcodex execrefuses to combine them.whytask now says to still run the synthesizer.forget_trust()removes this run's trust entries when the run ends. It drops only[projects."…"]tables under the run's output directory, and keeps the file mode.port/README.md: the smoke-test section documents both changes.Risk
--approve-for-me, Codex's automatic reviewer decides on escalation requests during smoke runs instead of failing them. That matches what a person approving prompts in a session does. Theforeign_seatcheck already accepts a seat the reviewer denied, as long as the run reports it.forget_trustedits~/.codex/config.tomlwhile nocodexprocess from the run is still going. It rewrites the file by replacing it with a temp file and keeps the mode. A config with no matching entries is left untouched.Proof
I probed the sandbox in a fresh repo:
.agentsand.codexcan't be written, and.claudeand.cursorcan.--approve-for-me, an escalatedmkdir -p .agents/skills/probeand anapply_patchadd under.agents/skills/both succeed.I reran
smoke.py --harness codex --only why,create-verification-skillwith this branch's harness line, and both passed:create-verification-skill: 2 checks, with the skill in.agents/skills/and linked from.claude/skills/.why: 5 checks, with the synthesizer spawned ongpt-6-astra.After that run,
config.tomlheld no trust entries from it.New unit tests:
run_codexpasses--approve-for-meand no sandbox flag.forget_trustremoves only the run's entries, keeps a sibling directory whose name shares the prefix, keeps the mode, and leaves a missing config alone.Each new test fails when its fix is undone: putting
-s workspace-writeback, or dropping the separator from the prefix check.All 257 unit tests pass, and
check.pyreports 0 problems.