Skip to content

fix(cli): send the cleanup percent in the policy target the server reads - #2937

Merged
Ingwannu merged 1 commit into
lidge-jun:devfrom
luvs01:agent/cli-cleanup-policy-percent
Aug 29, 2026
Merged

fix(cli): send the cleanup percent in the policy target the server reads#2937
Ingwannu merged 1 commit into
lidge-jun:devfrom
luvs01:agent/cli-cleanup-policy-percent

Conversation

@luvs01

@luvs01 luvs01 commented Aug 29, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Send ocx storage policy set --percent N as target: { removeOldestPercent: N }, the shape the cleanup-policy PUT route actually reads.
  • Update the existing wire-shape assertion and add regressions for the corrected shape and for out-of-range forwarding.

The defect

The CLI serialized a top-level percent field. That field is not part of the PUT contract: parseStorageCleanupPolicyInput spreads the body, but normalizeStorageCleanupPolicy reads the percent only from target, so an absent target key leaves the previously stored target in place.

The request still returned 200 with a policy body, so the operator saw success while nothing changed. On a policy holding the 25% default, --percent 10 reported success and left cleanup authorized to remove considerably more data than was requested. Reducing the percent is the direction an operator reaches for when they want to delete less, which is what makes the silent no-op consequential rather than cosmetic.

Scope

Client-side only. No server contract, validation vocabulary, or policy semantics change, and omission behavior for enabled, mode, and schedule is untouched.

An out-of-range percent is still forwarded rather than rejected locally. The server owns the 1-100 range and answers with a named 400; duplicating that vocabulary in the CLI would be a second thing to keep in sync, and a refused write is already the correct outcome. The failure being removed here is the silent accepted one.

Verification

  • Based on current dev@d882caed5eb2.
  • Bun 1.4.0+34cbb9a40, tests/cli-storage-inspect.test.ts: 21 passed, 0 failed.
  • Red-proven: with the source change reverted, 3 tests fail — the updated shape assertion plus both new regressions.
  • Bun 1.4.0+34cbb9a40, with tests/storage-policy-config-race.test.ts: 23 passed, 0 failed (68 expectations).
  • bun run typecheck: passed.
  • bun run privacy:scan: passed.
  • The repository-wide suite was intentionally not duplicated locally; hosted CI remains the full-matrix check.

Checklist

  • Scope stays focused and avoids unrelated cleanup.
  • Docs or release notes were updated when needed. The documented --percent usage is unchanged; only the wire shape it produces is corrected.
  • Security-sensitive changes were reviewed for secrets, auth, and unsafe defaults.

Review readiness checklist

  • All CI tests are green on my local testing.
  • I pushed my PR to the latest dev commit.
  • I resolved all correct Codex and CodeRabbit findings.
  • My PR is ready for review.

Summary by CodeRabbit

  • Bug Fixes

    • Fixed storage cleanup policy updates so the requested cleanup percentage is correctly applied.
    • Invalid percentage values are now sent to the server for clear validation errors instead of being silently ignored.
  • Tests

    • Added coverage for valid and out-of-range cleanup percentages.

`ocx storage policy set --percent N` serialized a top-level `percent` field. The
PUT contract has no such field: `normalizeStorageCleanupPolicy` reads only
`target`, so the value was dropped and the previously stored target survived.

The request still answered 200 with a policy body, so the operator saw success
while the stored target was unchanged. On a policy holding the 25% default,
`--percent 10` left cleanup authorized to remove considerably more data than was
asked for.

Send `target: { removeOldestPercent: N }` instead. Out-of-range values are still
forwarded so the server answers with its named 400 rather than the CLI
duplicating the 1-100 vocabulary; a rejected write is the correct outcome, and
the silent accepted write is what this removes.
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, add credits to your account and enable them for code reviews in your settings.

@github-actions

Copy link
Copy Markdown
Contributor

Deterministic PR hygiene checks passed.

@github-actions github-actions Bot added bug Something isn't working review-ready labels Aug 29, 2026
@github-actions

github-actions Bot commented Aug 29, 2026

Copy link
Copy Markdown
Contributor

✅ READY

  • all PR quality gates passed; the review readiness checklist is complete.

Review readiness checklist

  • ✅ All CI tests are green on my local testing.
  • ✅ I pushed my PR to the latest dev commit.
  • ✅ I resolved all correct Codex and CodeRabbit findings.
  • ✅ My PR is ready for review.

4/4 boxes ticked.

This pull request is already Ready for Review.
The review-ready label marks this PR as ready; review automation runs independently.
Maintainers: @lidge-jun @Ingwannu

@coderabbitai

coderabbitai Bot commented Aug 29, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 7df5ece8-f79e-4e88-8c44-32bf06008d1b

📥 Commits

Reviewing files that changed from the base of the PR and between d882cae and 69aec67.

📒 Files selected for processing (2)
  • src/cli/storage.ts
  • tests/cli-storage-inspect.test.ts

Included review availability: Your plan provides up to 10 included reviews per hour; 5 remain after this review.


📝 Walkthrough

Walkthrough

The storage policy CLI now sends --percent as target.removeOldestPercent. Tests verify the nested request shape, exclude the obsolete top-level field, and preserve server-side validation for out-of-range values.

Changes

Storage policy percent update

Layer / File(s) Summary
Nested percent payload and forwarding validation
src/cli/storage.ts:176-185, tests/cli-storage-inspect.test.ts:145-169
policy set --percent now sends target.removeOldestPercent instead of top-level percent. Tests verify valid values, absence of the obsolete field, and forwarding of 0 for server-side rejection.

Estimated code review effort: 2 (Simple) | ~10 minutes

Merge Risk: ⚪ Minimal · up to 69aec

The CLI now sends the cleanup percentage in the policy target the server reads, preventing successful no-op updates while preserving server-side range validation; no actionable merge-blocking risk remains.

Suggested reviewers: lidge-j

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 1 functions across 2 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: sending the CLI cleanup percentage inside the policy target field that the server reads. It matches the changes in src/cli/storage.ts and the…
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Full details: Title check

Explanation

The title clearly and concisely describes the main change: sending the CLI cleanup percentage inside the policy target field that the server reads. It matches the changes in src/cli/storage.ts and the related regression tests.

  • Fix all pre-merge checks with AI
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@lidge-jun

Copy link
Copy Markdown
Owner

리뷰 · 우선순위 73 / 80

이 PR은 지금 dev HEAD d882caed5 (#2936, Cursor가 다시 그리는 도구 결과에 그보다 앞에 있는 호출만 이름을 붙이게 함) 바로 위에서, ocx storage policy set --percent N 이 서버가 실제로 읽는 칸에 숫자를 안 넣던 구멍을 막는다. 미리보기 배포는 계획에 없고, types.ts/config.ts 분할과도 안 겹친다. 정책 타입은 이미 src/types/config.tsStorageCleanupPolicy 에 있고, 이번 파일은 그 타입을 건드리지 않는다.

쉽게 말하면 이렇다. 저장소 자동 정리 정책은 "오래된 보관 세션을 몇 퍼센트까지 지울지"를 target.removeOldestPercent 에 적어 둔다. 기본값은 25다. src/storage/policy.tsparseStorageCleanupPolicyInput 은 PUT 본문을 이전 정책 위에 덮어 쓰지만, 퍼센트는 맨 위 percent 칸이 아니라 target 안에서만 읽는다. normalizeStorageCleanupPolicy 도 같다. target 키가 없으면 예전에 저장된 목표를 그대로 둔다. 서버 PUT 은 src/server/management/logs-usage-routes.ts 551행이다. 계약에 없는 칸이 있어도 거절하지 않고, 본문이 맞으면 200 과 정책 전체를 돌려준다.

지금 HEAD 의 src/cli/storage.ts 176행은 --percent 10{ percent: 10 } 으로 보낸다. 서버는 그 칸을 모른다. 그래서 요청은 성공으로 보이고, 저장된 목표는 25% 그대로다. 퍼센트를 줄이는 사람은 보통 덜 지우려고 줄인다. 이 침묵은 겉만 고친 게 아니다. 정리 엔진이 요청보다 많이 지울 권한을 그대로 남겨 둔다. 켜진 정책이 스케줄대로 돌면, 운영자가 방금 줄였다고 믿은 숫자가 아니라 예전 25% 로 고른다.

대시보드는 이미 맞는 모양이다. gui/src/pages/Storage.tsxbuildBody 는 퍼센트 모드에서 { removeOldestPercent: N }target 안에 넣고, 1-100 밖은 저장 전에 막는다. GUI 저장은 되고 CLI 만 틀린 칸에 넣던 것이다. CLI 가 --enabled 를 빼는 쪽은 맞다. PUT 559행은 enabled 가 없으면 예전 값을 지킨다. 그 생략은 이미 테스트가 잠가 두었다. 틀린 건 퍼센트 칸의 위치뿐이다.

고치는 방법은 한 줄이다. body.percent = percent 대신 body.target = { removeOldestPercent: percent } 를 보낸다. 범위 밖 숫자는 CLI 가 막지 않는다. takeIntegerOption(..., { min: 0 }) 은 0 이상 정수만 통과시키고, 1-100 은 서버 isValidPolicyTarget 이 막는다. 거절은 이름이 붙은 400 이다. 침묵하고 200 을 주는 길만 없앤다. 한 번 지우는 ocx storage cleanup --percent 는 같은 파일 80행에서 100 초과를 로컬에서 거절한다. 정책 설정만 서버에 맡긴다. 작성자가 소스 변경을 되돌리면 모양 검사 하나와 회귀 둘, 합쳐 세 개가 빨개진다고 했다. 로컬에서 tests/cli-storage-inspect.test.ts 21개, tests/storage-policy-config-race.test.ts 23개, typecheck, privacy:scan 은 초록이다. 지금 깃허브 검사는 hygiene / enforce-target / label / resolve-pr / CodeRabbit 만 초록이고, 본 테스트 매트릭스는 아직 이 목록에 없다.

라인 176 - 고친 뒤 body.target 은 이전 target 과 합치지 않고 통째로 갈아 끼운다. 서버 parseStorageCleanupPolicyInput 218행도 o.target 이 있으면 예전 target 을 버린다. CLI 에 --reduce-to-bytes 가 없으니, 바이트 바닥(reduceToBytes)으로 저장해 둔 정책을 --percent 10 한 번으로 퍼센트 목표로 바꿔 버린다. GUI 는 모드를 고르고, CLI 는 퍼센트만 있다. 이번 버그의 핵심은 아니지만, 운영자가 바이트 목표를 퍼센트로 덮을 수 있다.
경로/심볼 - tests/cli-storage-inspect.test.ts 의 새 10% 테스트 - 바로 위 기존 테스트가 이미 { target: { removeOldestPercent: 40 } } 완전 일치라 맨 위 percent 칸도 없다. 10 전용 설명이 있긴 하다. 같은 모양을 두 숫자로 잠근 셈이다. 없어도 결함은 40% 줄에서 잡힌다.
경로/심볼 - 범위 밖 테스트 --percent 0 - 보내는 모양만 잠근다. 목 응답이 200 이라 서버의 named 400 문장은 이 파일이 증명하지 않는다. 101 도 같은 길인데 테스트가 없다. 한 번 지우는 cleanup 쪽은 100 초과를 로컬에서 거절하니까, 정책 설정만 서버로 넘긴다는 차이가 여기 있다.
경로/심볼 - src/cli/storage.ts USAGE 37행 - 도움말은 --percent <0-100> 이라고 적는다. 서버는 1-100 이고, 정책 설정 CLI 는 0 과 101 을 그대로 보낸다. 도움말과 실제가 어긋난다. 문서의 --percent 사용법은 안 바꿨다고 본문에 적혀 있다.
경로/심볼 - 서버가 맨 위 percent 를 무시한다는 고정장치 - 이번 PR 의 테스트는 CLI 송신 모양만 잠근다. 나중에 서버가 맨 위 percent 도 읽게 바꿔도 CLI 테스트는 초록으로 남는다. 이번 버그의 뿌리는 CLI 송신 모양이니 범위는 맞다. 서버 쪽 무시 동작은 이미 parseStorageCleanupPolicyInputtarget 만 읽는 코드로 드러난다.

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

  • 본 테스트 매트릭스가 이 헤드에서 초록이 된 뒤에 머지할지
  • 10% 중복 테스트를 이 PR에서 줄일지, 설명용으로 둘지
  • reduceToBytes 정책을 CLI --percent 가 통째로 바꿔도 되는지. 권장: 이번엔 두고, 후속에 도움말 한 줄
  • USAGE 의 0-100 을 서버 범위 1-100 에 맞출지, 범위 밖을 보내는 지금 선택을 도움말에 밝힐지
  • 관련 이슈가 안 묶여 있다. Add Storage page for Codex session usage and cleanup policy #42 는 정책 기능 자체이고, 이 송신 버그용 이슈는 없어도 된다

너의 추천
본 테스트가 이 헤드에서 초록이면 dev 로 머지하세요. GUI 가 이미 맞는 target.removeOldestPercent 를 보내는데 CLI 만 맨 위 percent 에 넣어서, 성공처럼 보이며 예전 25% 가 남던 침묵을 고쳤다. 범위 밖은 서버 400 으로 맡기는 선택이 본문에 적혀 있고, 테스트가 소스 되돌리면 빨개진다. types/config 분할과 무관하니 close-don't-rebase 대상이 아니다. 10% 중복 테스트와 USAGE 0-100 과 실제 1-100 의 어긋남, 바이트 목표를 퍼센트로 갈아 끼우는 점은 머지를 막을 정도는 아니다. 도움말은 후속으로 한 줄 고치면 된다. 머지 후 스냅샷에 cli-cleanup-policy-percent-target 정도만 적으면 된다.

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

@Ingwannu Ingwannu left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved exact head 69aec67 against dev@d882caed5eb212bf5737d3cb0022dace2dab418e.

This fixes a real accepted-no-op: the CLI sent percent at the top level while the management contract reads target.removeOldestPercent. The patch is limited to the CLI serializer and focused regression coverage, preserves server-owned range validation, and introduces no security-boundary or configuration-schema change.

My isolated review evidence remains green: 23/23 focused CLI/storage-policy tests and typecheck. Exact-head Cross-platform CI, React Doctor, macOS, storage-policy, API-usage, keyring, npm-global, hygiene, enforce-target, and CodeRabbit checks are all successful; there are no unresolved review threads.

@Ingwannu
Ingwannu merged commit dd159db into lidge-jun:dev Aug 29, 2026
27 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working review-ready

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants