Skip to content

fix(config): preserve prompt drafts and bound configuration access - #5540

Closed
luvs01 wants to merge 10 commits into
stack/codex-catalog-policyfrom
stack/codex-prompt-config
Closed

luvs01 wants to merge 10 commits into
stack/codex-catalog-policyfrom
stack/codex-prompt-config

Conversation

@luvs01

@luvs01 luvs01 commented Sep 22, 2026

Copy link
Copy Markdown
Collaborator

Summary

Consolidate #5232, #5274, #5368, #5367, and #5284 into one prompt/configuration integrity layer above #5529 in Stack #5505.

  • Preserve escaped external TOML paths and refuse unsafe integer rewrites without modifying the user's file.
  • Make supplied prompt-variant IDs edit-only and enforce the existing prompt-body size boundary at the management API.
  • Preserve parked edits while navigating prompt layers. Saving the displayed layer now clearly confirms that other layers' unsaved edits will be discarded; closing still offers the separate Discard action. All ten locales are updated.
  • Bound project configuration reads to a regular-file descriptor, refuse a substituted FIFO without waiting on POSIX, and reject detected growth or truncation instead of interpreting partial content.
  • Preserve all six source commits and attribution. Follow-ups address the source reviews' file-opening race and misleading Save confirmation, then align the route regression with the lower layer's known collaboration tag.

Screenshot

Real CustomLayerDialog and production styles rendered in headless Chrome with two synthetic prompt layers. DOM readback verified the confirmation wording, visible Save control, and absence of save/close side effects before confirmation.

Prompt save confirmation

Verification

  • Final head e352aee0343548a606a8d071b3504848c7503a41, above parent d11f35f56f1da8bcf38e9db788d14892a49c31ee.
  • Prepared source aggregate: 200 runtime/configuration tests and 20 GUI/locale tests passed; GUI TypeScript, production build, i18n, structure, privacy, and ratchet checks passed.
  • Combined Stack run: 190 passed and one stale route assertion failed because the lower layer already maps collaboration_mode. The follow-up explicitly distinguishes known-but-not-rendered collaboration from unknown layers; complete route/probe rerun passed 119 tests, 1 POSIX skip, 995 assertions, 0 failures. Other combined runtime/configuration cases passed in the first run.
  • Combined GUI/locale rerun: 20 passed / 183 assertions. Final TypeScript, structure SSOT, file-size ratchet, privacy scan, i18n and whitespace checks passed. The latest dev 7bd9985963fd344a2c512fa5cf3c0f57f6ba83bd merges without conflicts; no full merge-result suite claim is made.
  • FIFO/symlink execution on POSIX, docs-site build, full-suite/cross-platform CI and independent review remain pending. This PR stays draft. No file-size cap, baseline, runtime boundary, or source test timeout was relaxed.

Checklist

  • Scope stays focused and avoids unrelated cleanup.
  • Docs or release notes were updated when needed.
  • Security-sensitive changes were reviewed for secrets, auth, and unsafe defaults.

(cherry picked from commit 1131bf5)
(cherry picked from commit 38d56c5a6e527779b26eefb7c5d61b0adb3dd14e)
A caller-supplied id used the delete-or-edit existence check, so naming a syntactically valid but missing id bypassed the variant cap. Caller ids are now edit-only. The PUT base route also stored the raw body without normalization or the 64 KiB cap used elsewhere.

Signed-off-by: luvs01 <27862058+luvs01@users.noreply.github.com>
(cherry picked from commit 0be3292)
(cherry picked from commit 8540f69c15eea4f329bdc8e3c60d9e0c519db320)
In-dialog navigation parked drafts in memory, but the close/save guard only considered the currently visible layer, so edits parked on other layers were silently discarded. Track whether any parked draft differs from its persisted sibling and route close and save through the existing discard confirmation so unsaved custom prompt-layer text is never lost without a prompt.

(cherry picked from commit 23cf7a3)
(cherry picked from commit a1e9f1369ea66141caf362343a4e80990c5a3b73)
Discovery accepted any .codex/config.toml via existsSync and the collector synchronously readFileSync-read project configs with no type or size checks, so a symlinked special device or a huge file could hang or exhaust the process. Open candidates with O_NOFOLLOW, verify a regular file under a 1 MiB cap with fstat, and read through a bounded descriptor; lstat rejects non-regular or oversized candidates before discovery.

(cherry picked from commit 585e530)
(cherry picked from commit fb2d3f0646d9d4779caa048e01092f62f9dbe1c5)
…hem rounded

tomlScalar accepted any finite number, but Bun.TOML.parse already rounds integers outside JavaScript's safe range, so rewriting a user config silently changed their values. Throw UnserializableValueError so apply/disable refuse and leave the file untouched.

(cherry picked from commit bb125d6)
(cherry picked from commit 8b86eb0e6dd7a0d14d7632ec443141bfe819462b)
Managed TOML rewrites now state that an integer outside JavaScript's safe
range refuses the write and leaves the file unchanged, matching the guard in
src/integrations/serialize.ts.

(cherry picked from commit 28c2bab)
(cherry picked from commit ea030be176a4f5ade27e83af25fe2816cfd5eba2)
Open discovered candidates without blocking on a substituted FIFO, use platform-safe flag fallbacks, and allocate only the observed size plus one byte. Reject growth and truncation instead of analyzing a partial document. Cover reader boundaries and a bounded POSIX FIFO child.

(cherry picked from commit 06512682c0d549290ee73f7df78c30d33dd89967)
Distinguish saving the displayed layer from discarding edits on close in every locale. Recheck parked drafts when saved siblings change, preserve drafts through Keep editing, and verify close discards without writing.

(cherry picked from commit 9e4ac33fee287e3eb9f88fc5d43e17a6ad224aaa)
(cherry picked from commit 9f2f2eac8a3192e31bcecc17cb83e7117d0ddb0e)
@coderabbitai

coderabbitai Bot commented Sep 22, 2026

Copy link
Copy Markdown
Contributor

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@luvs01
luvs01 added this pull request to stack #5505 September 22, 2026 11:50
@github-actions

Copy link
Copy Markdown
Contributor

Deterministic PR hygiene checks passed.

@lidge-jun

Copy link
Copy Markdown
Owner

리뷰 · 우선순위 61 / 80

이 PR은 프롬프트·설정이 사용자 파일을 함부로 바꾸지 않도록 막는 안전망을 한곳에 모은 작업입니다. 바깥에서 쓴 TOML 경로(이스케이프 포함)는 그대로 외부로 두고, 안전한 정수 범위를 넘는 값은 반올림해 다시 쓰지 않고 거절합니다. 프롬프트 변형 ID는 새로 만들기용이 아니라 수정만 되게 막고, 본문 크기 한도는 관리 API에서도 지킵니다. GUI에서는 레이어를 오가며 잠깐 넣어 둔 초안을 닫기/저장 전에 알려 주고, 프로젝트 설정 읽기는 일반 파일만·크기 제한·FIFO에 멈추지 않게 읽습니다. 아래쪽 스택(#5529 위, base stack/codex-catalog-policy)에 올리는 draft이며, 소스 PR(#5232·#5274·#5368·#5367·#5284)은 이미 닫혀 있습니다.

라인 - gui/src/components/codex-set/CustomLayerDialog.tsx · 닫기 확인은 여전히 discardPrompt("Discard your changes?")인데, 지금 레이어는 깨끗하고 다른 레이어에만 parked 초안이 있을 때도 같은 문구라 저장 쪽 discardOthersAndSave보다 덜 분명합니다.
라인 - src/codex/project-config-warnings.ts · readBoundedProjectConfig / discover가 심볼릭 링크·FIFO·초과 크기·읽기 중 크기 변화를 모두 null/스킵으로 처리해, 진단 경고가 그냥 안 나옵니다. 의도적 fail-closed라면 괜찮지만 운영자가 “왜 이 프로젝트가 빠졌지?”를 알기 어렵습니다.
라인 - src/codex/project-config-warnings.ts · O_NOFOLLOW/O_NONBLOCK이 없으면 ?? 0으로 빠집니다. 작성자도 POSIX FIFO 검증을 아직이라고 했고, 플래그가 없는 환경에서는 막힘 위험이 남습니다.
라인 - src/codex/prompt-layers.ts · model_instructions_file을 읽지 못할 때 "<unreadable model_instructions_file>" 센티널 문자열을 경로처럼 씁니다. fail-closed 방향은 맞지만, 나중에 이 문자열이 실제 경로/표시에 섞이면 헷갈릴 수 있습니다.
라인 - base가 dev가 아니라 stack/codex-catalog-policy입니다. 스택 합본 목적에는 맞지만, dev로 합치기 전에 아래 레이어(#5529 등)와 충돌·회귀 범위는 메인테이너가 한 번 더 맞춰야 합니다.

메인테이너의 판단이 필요한 지점

진단에서 “위험한 후보는 조용히 건너뛰기”를 계속할지, 아니면 skip 이유를 로그/경고로 남길지. draft를 유지한 채 POSIX FIFO·심볼릭 링크 실행 검증을 머지 조건으로 둘지. 닫기 확인 문구를 저장 확인처럼 “다른 레이어 초안”을 명시할지.

너의 추천

방향은 좋고 테스트도 핵심 회귀를 잡습니다. draft·스택 base 상태를 유지한 뒤, FIFO/심볼릭 링크 검증과 닫기 문구 정리를 짧게 하고 스택이 dev로 올라갈 때 같이 넣는 편이 안전합니다. types.ts/config.ts 분할 이슈나 preview deploy 이야기는 이 PR 범위 밖입니다. 소스 PR은 이미 닫혀 있으니 추가로 닫을 대상은 없습니다.

이 댓글은 grok-bot이 작성했습니다

@lidge-jun

Copy link
Copy Markdown
Owner

Superseded by #5609, which is open and not yet merged. Cherry-picked (authored by you): 9e0404f, fce8ffb, 0f0383b, a5b551c, 1e25a21. Reimplemented with you as co-author: 1da10c9 + 2f4f8f9 (the confirmation Save now re-runs the ordinary validation and keeps its target fixed), 62c8932 + 3a5674f (bounded project-config reads) and e352aee (the collaboration test). The TOML read fallback now also decodes unicode-escaped instruction paths, and the Korean and Traditional Chinese API headings are translated. Thank you!

@lidge-jun lidge-jun closed this Sep 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants