fix(codex): remap dot-prefixed bootstrap context

This commit is contained in:
Vincent Koc
2026-05-14 13:53:15 +08:00
parent 65ea6fdb49
commit 9518d12e13
3 changed files with 33 additions and 2 deletions

View File

@@ -16,7 +16,7 @@ Docs: https://docs.openclaw.ai
- iOS: restore first-use Contacts, Calendar, and Reminders permission prompts and add Privacy & Access status/actions in Settings. Thanks @BunsDev.
- Canvas: return not found for malformed percent-encoded Canvas/A2UI/document asset paths and keep decoded parent traversal blocked before path normalization.
- Telegram: allow trusted local Bot API media files whose filenames start with dots instead of falling back to remote download.
- Agents: remap injected context files under dot-dot-prefixed workspace directories when a run switches to an effective sandbox workspace.
- Agents/Codex app-server: remap injected context files under dot-dot-prefixed workspace directories when a run switches to an effective sandbox workspace.
- Agents: allow dot-dot-prefixed filenames such as `..note.txt` through sandbox FS bridge, remote sandbox reads, and apply_patch summaries without mistaking the name for parent traversal.
- CLI/migrate: hide per-item source/plugin hints on non-conflicting Codex skill and plugin selection prompts, keeping the hint text reserved for rows that actually need attention. Thanks @sjf.
- Codex harness: treat high-confidence app-server OAuth refresh invalidation as a terminal auth-profile failure, stopping repeated raw token-refresh errors without turning entitlement or usage-limit payloads into re-auth prompts.

View File

@@ -2371,6 +2371,35 @@ describe("runCodexAppServerAttempt", () => {
expect(config?.instructions).toBeUndefined();
});
it("remaps Codex bootstrap files under dot-prefixed workspace directories", () => {
expect(
__testing.remapCodexContextFilePath({
file: {
path: "/real/workspace/..context/SOUL.md",
content: "Soul voice goes here.",
},
sourceWorkspaceDir: "/real/workspace",
targetWorkspaceDir: "/sandbox/workspace",
}),
).toEqual({
path: "/sandbox/workspace/..context/SOUL.md",
content: "Soul voice goes here.",
});
expect(
__testing.remapCodexContextFilePath({
file: {
path: "/outside/SOUL.md",
content: "outside",
},
sourceWorkspaceDir: "/real/workspace",
targetWorkspaceDir: "/sandbox/workspace",
}),
).toEqual({
path: "/outside/SOUL.md",
content: "outside",
});
});
it("keeps lightweight cron Codex turns out of OpenClaw bootstrap context", async () => {
const sessionFile = path.join(tempDir, "session.jsonl");
const workspaceDir = path.join(tempDir, "workspace");

View File

@@ -3050,7 +3050,8 @@ function remapCodexContextFilePath(params: {
const relativePath = path.relative(params.sourceWorkspaceDir, params.file.path);
if (
!relativePath ||
relativePath.startsWith("..") ||
relativePath === ".." ||
relativePath.startsWith(`..${path.sep}`) ||
path.isAbsolute(relativePath) ||
params.sourceWorkspaceDir === params.targetWorkspaceDir
) {
@@ -3214,6 +3215,7 @@ export const __testing = {
filterCodexDynamicToolsForAllowlist,
filterToolsForVisionInputs,
handleDynamicToolCallWithTimeout,
remapCodexContextFilePath,
resolveDynamicToolCallTimeoutMs,
restrictCodexAppServerSandboxForOpenClawSandbox,
resolveOpenClawCodingToolsSessionKeys,