Skip to content

feat(review): add lane-based Codex review loop - #68

Merged
choi138 merged 7 commits into
mainfrom
feature/codex-review-loop
Aug 4, 2026
Merged

feat(review): add lane-based Codex review loop#68
choi138 merged 7 commits into
mainfrom
feature/codex-review-loop

Conversation

@choi138

@choi138 choi138 commented Aug 3, 2026

Copy link
Copy Markdown
Owner

Summary

  • Add a repository-local codex-review-loop skill with a baseline lane and seven specialist lanes.
  • Support uncommitted, base-branch, and commit review scopes with structured P0-P3 findings.
  • Add sensitive-path fail-closed handling, child-review recursion prevention, explicit fix gates, and bounded re-review.
  • Register the skill in activation rules and document it as the local review source of truth.

Why

Provide a repeatable local review workflow that keeps review read-only until fixes are explicitly approved, while leaving all GitHub writes outside the review loop.

Validation

  • 18 contract, routing, merge, sensitive-path, runner, and activation tests passed.
  • Skill validator passed.
  • ShellCheck and Bash syntax checks passed.
  • Lane registry, finding schema, and skill rules JSON parsed successfully.
  • git diff --check and commit hooks passed.

Summary by CodeRabbit

  • 새로운 기능
    • 변경 범위에 따라 전문 검토를 자동 선택·실행하는 Codex 리뷰 루프를 추가했습니다.
    • 검토 결과를 검증·통합하고 우선순위와 중복 이슈를 정리합니다.
    • 읽기 전용 검토, 민감 정보 보호, 승인 기반 수정 및 재검토를 지원합니다.
  • 문서
    • 사용량, 보안, 동시성, 빌드, 테스트 등 검토 기준과 검증 절차를 문서화했습니다.
  • 버그 수정
    • 하위 리뷰어 실행 시 리뷰 루프가 중복 활성화되지 않도록 개선했습니다.
  • 테스트
    • 검토 범위 라우팅, 결과 병합, 안전성 및 활성화 동작을 자동 검증합니다.
    • 지속적 통합 환경에서 관련 검증을 자동 실행합니다.

@coderabbitai

coderabbitai Bot commented Aug 3, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Codex 기반 리뷰 루프를 추가했습니다. Git 범위를 해석하고 specialist lane을 선택합니다. Codex 결과를 검증하고 finding을 병합합니다. 승인된 수정과 최대 3회의 재검토 절차를 정의했습니다.

Changes

Codex 리뷰 루프

Layer / File(s) Summary
리뷰 계약과 lane 정의
.agents/skills/codex-review-loop/SKILL.md, .agents/skills/codex-review-loop/agents/*, .agents/skills/codex-review-loop/references/*
읽기 전용 리뷰, 승인 기반 수정, 검증 프로파일, reviewer JSON Schema와 전문 lane 기준을 추가했습니다.
리뷰 범위 해석과 활성화
.agents/hooks/skill_activation.ts, .agents/skills/codex-review-loop/scripts/review_scope_git.py, .agents/skills/codex-review-loop/scripts/review_git_process.py, .agents/skills/codex-review-loop/scripts/resolve_review_scope.py
uncommitted, base, commit 범위를 해석하고 변경 경로와 의미 신호에 따라 lane을 활성화합니다. 안전하지 않은 범위와 제한된 semantic inspection을 처리합니다.
lane 실행과 결과 병합
.agents/skills/codex-review-loop/scripts/run_review_lane.sh, .agents/skills/codex-review-loop/scripts/finding_validation.py, .agents/skills/codex-review-loop/scripts/merge_findings.py
Codex 실행 입력과 결과를 검증하고, 여러 lane의 중복 finding을 우선순위와 근거와 함께 병합합니다.
통합 검증과 CI 연결
.agents/skills/codex-review-loop/tests/*, .agents/skills/skill-rules.json, .github/workflows/ci.yml, AGENTS.md, .gitignore
활성화 훅, 범위 라우팅, 보안 경계, runner 계약, finding 병합을 테스트하고 CI에서 테스트를 실행합니다.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Developer
  participant run_review_lane.sh
  participant resolve_review_scope.py
  participant Codex
  participant merge_findings.py
  Developer->>run_review_lane.sh: 리뷰 범위와 lane 지정
  run_review_lane.sh->>resolve_review_scope.py: 범위 해석 요청
  resolve_review_scope.py-->>run_review_lane.sh: 활성 lane과 검증 프로파일 반환
  run_review_lane.sh->>Codex: reviewer prompt와 변경 범위 전달
  Codex-->>run_review_lane.sh: JSON finding 결과 작성
  run_review_lane.sh->>merge_findings.py: 결과 schema 검증
  merge_findings.py-->>Developer: 병합된 리뷰 결과 반환
Loading

Possibly related PRs

  • choi138/toki#26: agent 설정과 활성화 훅을 함께 변경합니다.

Poem

토끼가 범위를 찾아 깡충,
lane이 차례로 검토해요.
finding은 하나로 모이고,
승인된 patch만 고쳐요.
최대 세 번 다시 확인해요.

🚥 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%. 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 제목은 lane 기반 Codex 리뷰 루프 추가라는 PR의 주요 변경 사항을 간결하고 명확하게 설명합니다.
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.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/codex-review-loop

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.

@choi138
choi138 marked this pull request as ready for review August 3, 2026 03:24

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e2ba25fe8b

ℹ️ 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".

Comment thread .agents/skills/codex-review-loop/scripts/resolve_review_scope.py Outdated
Comment thread .agents/skills/codex-review-loop/scripts/resolve_review_scope.py Outdated
Comment thread .agents/skills/codex-review-loop/scripts/merge_findings.py Outdated
Comment thread .agents/skills/codex-review-loop/scripts/run_review_lane.sh Outdated
Comment thread .agents/skills/skill-rules.json
Comment thread .agents/skills/codex-review-loop/scripts/merge_findings.py Outdated
@choi138 choi138 added the 🤖 codex: needs work Codex raised issues on the current PR head that still need work label Aug 3, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (1)
.agents/skills/codex-review-loop/references/schemas/review-findings.schema.json (1)

17-86: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick win

스키마 제약을 merge_findings.py의 검증 규칙과 맞추십시오.

merge_findings.pyvalidate_lane_result는 lane result의 필드 집합, schemaVersion, lane 형식, verdict, findings 배열, priority, confidence 범위(0-1), title/rootCause/evidence/impact/suggestedFix의 비어 있지 않음, 저장소 상대 경로, startLine/endLine, verification 배열의 비어 있지 않은 문자열을 강제합니다. 이 스키마 파일에는 이러한 제약 중 다수(confidence 범위, 문자열 최소 길이, verification 최소 항목 수, startLine 최소값, lane 패턴)가 없습니다.

Codex는 --output-schema로 이 스키마만 보고 출력을 생성합니다. 스키마가 느슨하면 스키마상 유효하지만 merge_findings.py에서 거부되는 출력을 생성할 수 있고, 이는 Codex 호출 낭비와 재실행으로 이어집니다.

♻️ 제안된 스키마 강화
     "lane": {
-      "type": "string"
+      "type": "string",
+      "pattern": "^[a-z0-9]+(-[a-z0-9]+)*$"
     },
     "verdict": {
       "type": "string",
       "enum": ["clean", "findings"]
     },
     "summary": {
-      "type": "string"
+      "type": "string",
+      "minLength": 1
     },
     "findings": {
       "type": "array",
       "items": {
         "type": "object",
         "additionalProperties": false,
         ...
         "properties": {
           "priority": {
             "type": "string",
             "enum": ["P0", "P1", "P2", "P3"]
           },
           "confidence": {
-            "type": "number"
+            "type": "number",
+            "minimum": 0,
+            "maximum": 1
           },
           "title": {
-            "type": "string"
+            "type": "string",
+            "minLength": 1
           },
           "file": {
             "type": "string"
           },
           "startLine": {
-            "type": "integer"
+            "type": "integer",
+            "minimum": 1
           },
           "endLine": {
-            "type": "integer"
+            "type": "integer",
+            "minimum": 1
           },
           "rootCause": {
-            "type": "string"
+            "type": "string",
+            "minLength": 1
           },
           "evidence": {
-            "type": "string"
+            "type": "string",
+            "minLength": 1
           },
           "impact": {
-            "type": "string"
+            "type": "string",
+            "minLength": 1
           },
           "suggestedFix": {
-            "type": "string"
+            "type": "string",
+            "minLength": 1
           },
           "verification": {
             "type": "array",
+            "minItems": 1,
             "items": {
-              "type": "string"
+              "type": "string",
+              "minLength": 1
             }
           }
         }
       }
     }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
@.agents/skills/codex-review-loop/references/schemas/review-findings.schema.json
around lines 17 - 86, Align the review-findings JSON schema with
merge_findings.py’s validate_lane_result rules: add the required schemaVersion
and lane constraints, enforce the exact allowed field set, validate verdict and
findings as required, constrain priority and confidence to their accepted
values/range, require non-empty title/rootCause/evidence/impact/suggestedFix,
enforce repository-relative file paths and startLine/endLine minimums, and
require verification to contain non-empty strings with the validator’s minimum
count. Update the corresponding required/properties definitions so Codex output
accepted by the schema is also accepted by validate_lane_result.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.agents/skills/codex-review-loop/references/lane-registry.json:
- Around line 3-18: 보안 파일이 리뷰 범위에 포함되지 않도록 `pathExclusions`에 `.env`, `*.pem`,
`*.key`, `*.p12`, `id_rsa*` 패턴과 필요한 변형을 추가하세요. 기존 디렉터리 제외 항목은 유지하고,
`safeToReview: true` 경로에서도 일반적인 자격증명 파일이 fail-closed로 제외되도록 구성하세요.

In @.agents/skills/codex-review-loop/scripts/merge_findings.py:
- Line 32: Update WORD_RE and the normalized_words flow used by finding_id and
similarity to tokenize Unicode letters and numbers, not only ASCII characters.
Preserve the existing normalization, hashing, and similarity behavior while
ensuring non-ASCII-only titles or rootCause values produce meaningful tokens,
distinct finding IDs, and token-based similarity.

In @.agents/skills/codex-review-loop/scripts/run_review_lane.sh:
- Around line 142-156: Update the codex review invocation in the
TOKI_REVIEW_CHILD subshell to avoid passing scope arguments from
codex_scope_args together with the stdin prompt marker "-". Preserve the
selected review scope by invoking codex with the scope flags only, and remove
the conflicting prompt input path for this review-mode call.

---

Nitpick comments:
In
@.agents/skills/codex-review-loop/references/schemas/review-findings.schema.json:
- Around line 17-86: Align the review-findings JSON schema with
merge_findings.py’s validate_lane_result rules: add the required schemaVersion
and lane constraints, enforce the exact allowed field set, validate verdict and
findings as required, constrain priority and confidence to their accepted
values/range, require non-empty title/rootCause/evidence/impact/suggestedFix,
enforce repository-relative file paths and startLine/endLine minimums, and
require verification to contain non-empty strings with the validator’s minimum
count. Update the corresponding required/properties definitions so Codex output
accepted by the schema is also accepted by validate_lane_result.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 1d5d8f32-c22d-4567-a7d3-033082f55cda

📥 Commits

Reviewing files that changed from the base of the PR and between 3a7b258 and e2ba25f.

📒 Files selected for processing (25)
  • .agents/hooks/skill_activation.ts
  • .agents/skills/codex-review-loop/SKILL.md
  • .agents/skills/codex-review-loop/agents/openai.yaml
  • .agents/skills/codex-review-loop/references/lane-registry.json
  • .agents/skills/codex-review-loop/references/lanes/baseline.md
  • .agents/skills/codex-review-loop/references/lanes/build-portability.md
  • .agents/skills/codex-review-loop/references/lanes/concurrency-lifecycle.md
  • .agents/skills/codex-review-loop/references/lanes/privacy-security.md
  • .agents/skills/codex-review-loop/references/lanes/remote-sync.md
  • .agents/skills/codex-review-loop/references/lanes/swiftui-architecture.md
  • .agents/skills/codex-review-loop/references/lanes/testing.md
  • .agents/skills/codex-review-loop/references/lanes/usage-pricing.md
  • .agents/skills/codex-review-loop/references/prompts/reviewer.md
  • .agents/skills/codex-review-loop/references/schemas/review-findings.schema.json
  • .agents/skills/codex-review-loop/references/verification.md
  • .agents/skills/codex-review-loop/scripts/merge_findings.py
  • .agents/skills/codex-review-loop/scripts/resolve_review_scope.py
  • .agents/skills/codex-review-loop/scripts/run_review_lane.sh
  • .agents/skills/codex-review-loop/tests/test_activation_hook.py
  • .agents/skills/codex-review-loop/tests/test_finding_merge.py
  • .agents/skills/codex-review-loop/tests/test_runner_contract.py
  • .agents/skills/codex-review-loop/tests/test_scope_routing.py
  • .agents/skills/skill-rules.json
  • .gitignore
  • AGENTS.md

Comment thread .agents/skills/codex-review-loop/references/lane-registry.json
Comment thread .agents/skills/codex-review-loop/scripts/merge_findings.py Outdated
Comment thread .agents/skills/codex-review-loop/scripts/run_review_lane.sh Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
.github/workflows/ci.yml (1)

21-27: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Node 22 호환성을 고려해 --experimental-strip-types 사용을 제거하거나 CI Node 버전을 고정하십시오.

Node 22.18 이상에서는 타입 스트립이 기본적으로 활성화됩니다. .github/workflows/ci.ymlnode-version: 22가 최신 패치를 설치할 수 있어 테스트 의도와 실행 환경이 달라질 수 있습니다. subprocess.run(..., check=True) 경로에서 Node 플래그 변경이 CI 실패로 이어지지 않도록 테스트를 최신 Node 22 동작에 맞추고, 특정 패치에서 CI를 실행하려면 node-version을 고정하십시오.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/ci.yml around lines 21 - 27, Pin the Node.js version in
the “Set up Node.js for review-loop hook tests” step to an exact Node 22 patch
version compatible with the existing test commands, rather than the floating
`22` alias. Keep the `Test Codex review loop` command unchanged and ensure CI
consistently uses the intended Node behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In @.github/workflows/ci.yml:
- Around line 21-27: Pin the Node.js version in the “Set up Node.js for
review-loop hook tests” step to an exact Node 22 patch version compatible with
the existing test commands, rather than the floating `22` alias. Keep the `Test
Codex review loop` command unchanged and ensure CI consistently uses the
intended Node behavior.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 455f28af-b90a-446c-a625-83f70dbe9767

📥 Commits

Reviewing files that changed from the base of the PR and between e2ba25f and 995c822.

📒 Files selected for processing (15)
  • .agents/skills/codex-review-loop/references/lane-registry.json
  • .agents/skills/codex-review-loop/references/prompts/reviewer.md
  • .agents/skills/codex-review-loop/scripts/finding_validation.py
  • .agents/skills/codex-review-loop/scripts/merge_findings.py
  • .agents/skills/codex-review-loop/scripts/resolve_review_scope.py
  • .agents/skills/codex-review-loop/scripts/review_git_process.py
  • .agents/skills/codex-review-loop/scripts/review_scope_git.py
  • .agents/skills/codex-review-loop/scripts/run_review_lane.sh
  • .agents/skills/codex-review-loop/tests/test_activation_hook.py
  • .agents/skills/codex-review-loop/tests/test_finding_merge.py
  • .agents/skills/codex-review-loop/tests/test_runner_contract.py
  • .agents/skills/codex-review-loop/tests/test_scope_routing.py
  • .agents/skills/codex-review-loop/tests/test_scope_security.py
  • .agents/skills/skill-rules.json
  • .github/workflows/ci.yml
🚧 Files skipped from review as they are similar to previous changes (4)
  • .agents/skills/skill-rules.json
  • .agents/skills/codex-review-loop/references/lane-registry.json
  • .agents/skills/codex-review-loop/references/prompts/reviewer.md
  • .agents/skills/codex-review-loop/scripts/run_review_lane.sh

@choi138 choi138 removed the 🤖 codex: needs work Codex raised issues on the current PR head that still need work label Aug 3, 2026
@choi138

choi138 commented Aug 3, 2026

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 995c822318

ℹ️ 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".

Comment thread .agents/skills/codex-review-loop/scripts/review_scope_git.py
Comment thread .agents/skills/codex-review-loop/scripts/review_scope_git.py Outdated
Comment thread .agents/skills/codex-review-loop/scripts/merge_findings.py
@choi138 choi138 added the 🤖 codex: needs work Codex raised issues on the current PR head that still need work label Aug 3, 2026
@choi138 choi138 removed the 🤖 codex: needs work Codex raised issues on the current PR head that still need work label Aug 3, 2026
@choi138

choi138 commented Aug 3, 2026

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d395584fc7

ℹ️ 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".

Comment thread .agents/skills/codex-review-loop/scripts/review_scope_git.py Outdated
Comment thread .agents/skills/codex-review-loop/scripts/finding_validation.py Outdated
Comment thread .agents/skills/codex-review-loop/scripts/review_scope_git.py Outdated
@choi138 choi138 added the 🤖 codex: needs work Codex raised issues on the current PR head that still need work label Aug 3, 2026
@choi138 choi138 removed the 🤖 codex: needs work Codex raised issues on the current PR head that still need work label Aug 3, 2026
@choi138

choi138 commented Aug 3, 2026

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 150d3aa385

ℹ️ 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".

Comment thread .agents/skills/codex-review-loop/references/lane-registry.json
Comment thread .agents/skills/codex-review-loop/scripts/review_scope_git.py Outdated
Comment thread .agents/skills/codex-review-loop/scripts/review_scope_git.py
Comment thread .agents/skills/codex-review-loop/scripts/finding_validation.py Outdated
@choi138 choi138 added the 🤖 codex: needs work Codex raised issues on the current PR head that still need work label Aug 3, 2026
@choi138 choi138 removed the 🤖 codex: needs work Codex raised issues on the current PR head that still need work label Aug 3, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 23f681744f

ℹ️ 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".

Comment thread .agents/skills/codex-review-loop/scripts/review_scope_git.py Outdated
Comment thread .agents/skills/codex-review-loop/scripts/finding_validation.py Outdated
@choi138 choi138 added the 🤖 codex: needs work Codex raised issues on the current PR head that still need work label Aug 3, 2026
@choi138 choi138 removed the 🤖 codex: needs work Codex raised issues on the current PR head that still need work label Aug 3, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
.agents/skills/codex-review-loop/scripts/review_git_process.py (1)

35-73: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick win

filter.process 무력화 시나리오에 대한 전용 테스트가 없습니다.

git_environment_without_filtersclean, smudge, process, required 중 하나라도 설정된 드라이버를 발견하면 네 가지 항목을 모두 재정의합니다. GIT_CONFIG_KEY/GIT_CONFIG_VALUE 환경변수 오버라이드는 설정 파일의 값보다 우선하므로, 원본 악성 명령은 어떤 경우에도 실행되지 않습니다. 이 설계 자체는 타당합니다.

다만 test_scope_security.pytest_runner_contract.py의 clean filter 테스트는 filter.<driver>.clean만 설정합니다. filter.<driver>.process가 설정된 드라이버는 clean/smudge보다 항상 우선 적용되는데(long-running process filter가 우선), 이 경로를 검증하는 테스트가 없습니다. process 오버라이드 값이 빈 문자열일 때 Git이 이를 실제로 무력화(no-op)로 처리하는지, 혹은 실행 실패로 처리되어 required=false로 인해 원본 콘텐츠로 안전하게 대체되는지 확인하는 회귀 테스트를 추가하는 것이 좋습니다.

Git이 빈 filter.<driver>.process 값을 어떻게 처리하는지 최신 문서로 확인해 주시겠습니까?

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.agents/skills/codex-review-loop/scripts/review_git_process.py around lines
35 - 73, Verify from current Git documentation how an empty
filter.<driver>.process override is handled, then add dedicated regression
coverage in the existing test_scope_security.py and test_runner_contract.py
filter tests. Configure a driver with process (and required as applicable),
exercise the relevant Git operation, and assert the malicious process is never
executed while the result follows Git’s documented no-op or safe fallback
behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In @.agents/skills/codex-review-loop/scripts/review_git_process.py:
- Around line 35-73: Verify from current Git documentation how an empty
filter.<driver>.process override is handled, then add dedicated regression
coverage in the existing test_scope_security.py and test_runner_contract.py
filter tests. Configure a driver with process (and required as applicable),
exercise the relevant Git operation, and assert the malicious process is never
executed while the result follows Git’s documented no-op or safe fallback
behavior.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: f4ca8a5f-65b9-44aa-b7e0-0fd5fe16d625

📥 Commits

Reviewing files that changed from the base of the PR and between 150d3aa and 83e133d.

📒 Files selected for processing (9)
  • .agents/skills/codex-review-loop/references/lane-registry.json
  • .agents/skills/codex-review-loop/scripts/finding_validation.py
  • .agents/skills/codex-review-loop/scripts/review_git_process.py
  • .agents/skills/codex-review-loop/scripts/review_scope_git.py
  • .agents/skills/codex-review-loop/scripts/run_review_lane.sh
  • .agents/skills/codex-review-loop/scripts/run_with_safe_git.py
  • .agents/skills/codex-review-loop/tests/test_finding_merge.py
  • .agents/skills/codex-review-loop/tests/test_runner_contract.py
  • .agents/skills/codex-review-loop/tests/test_scope_security.py
🚧 Files skipped from review as they are similar to previous changes (3)
  • .agents/skills/codex-review-loop/scripts/run_review_lane.sh
  • .agents/skills/codex-review-loop/references/lane-registry.json
  • .agents/skills/codex-review-loop/scripts/review_scope_git.py

@choi138

choi138 commented Aug 3, 2026

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 83e133d1ad

ℹ️ 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".

Comment on lines +35 to +37
def git_environment_without_filters(repo: Path) -> dict[str, str]:
environment = dict(os.environ)
result = subprocess.run(

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Disable fsmonitor hooks before resolving scopes

When Git configures core.fsmonitor as an external hook, the resolver's worktree git diff commands execute that program before safeToReview is known; I reproduced this with a marker-writing hook and resolve_review_scope.py --uncommitted. The environment built here disables content filters but not fsmonitor, and it is also inherited by native Codex, so initiating a review can run arbitrary local tooling that mutates state or transmits sensitive data. Git documents that a pathname value for core.fsmonitor is treated as a hook command; override it to false for every resolver and child command and add a marker-hook regression test.

AGENTS.md reference: AGENTS.md:L33-L35

Useful? React with 👍 / 👎.

Comment on lines +219 to +220
def base_scope(repo: Path, base: str) -> tuple[list[str], bytes, bool]:
validate_base(repo, base)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Scan ignored sensitive files for base and commit reviews

When --base or --commit runs from a checkout containing an ignored sensitive file such as .env, these scope helpers inspect only paths in the selected Git diff and report safeToReview: true; native Codex can still open that worktree file while inspecting surrounding code. Fresh evidence beyond the earlier --uncommitted fix is that ignored_paths_matching is called only from uncommitted_scope; I reproduced both base and commit scopes returning no exclusions with an ignored .env present. Apply the ignored-exclusion scan to every scope or run reviews in a sanitized checkout, with regressions for both flags.

AGENTS.md reference: AGENTS.md:L33-L35

Useful? React with 👍 / 👎.

Comment on lines +157 to +159
untracked_roots = decode_z(
run_git(repo, ["ls-files", "--others", "--exclude-standard", "--directory", "-z"])
)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Reject ignored symlinks before uncommitted reviews

When an external symlink has an ordinary ignored name, --exclude-standard removes it from untracked, while ignored_paths_matching inventories only names matching sensitive-path patterns; the later symlink guard therefore never sees it and native --uncommitted review can follow its target. Fresh evidence beyond the previously fixed non-ignored symlink case is that I reproduced safeToReview: true with a tracked change plus an ignored link pointing to an external sensitive file. Inventory ignored symlinks independently of filename exclusions, fail closed before Codex invocation, and add this case to the symlink regressions.

AGENTS.md reference: AGENTS.md:L33-L35

Useful? React with 👍 / 👎.

Comment on lines +48 to +50
parts = path.split("/")
if any(part in {"", ".", ".."} for part in parts):
raise FindingError(

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Reject NUL bytes in finding paths

When a lane emits a valid JSON escape such as "bad\u0000name.swift", this path passes both strict UTF-8 encoding and the segment checks, and the merger accepts it unchanged; I reproduced both validation and merge succeeding. Any later filesystem or Git operation used to remediate the selected finding rejects the embedded NUL, so the generated RF-* entry cannot identify or fix a repository file. Reject NUL bytes in validate_repo_path and add validation-and-merge coverage for this input.

Useful? React with 👍 / 👎.

Comment on lines +89 to +90
if "baseline" not in seen_ids:
raise ScopeError("lane registry must include baseline")

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Require baseline to remain an always-on lane

When a caller supplies the supported --registry option with a baseline entry whose always field is false or absent, this validation accepts it, but a change matching no baseline path or semantic patterns activates no baseline review; run_review_lane.sh --lane baseline then refuses to run. This defeats the review loop's invariant that baseline correctness and security reasoning always apply. Require the baseline entry's always value to be the literal boolean true and add malformed-registry coverage.

AGENTS.md reference: AGENTS.md:L12-L12

Useful? React with 👍 / 👎.

Comment on lines +129 to +134
for finding in result["findings"]:
duplicate = next((group for group in groups if is_duplicate(group, finding)), None)
if duplicate is None:
groups.append(new_group(lane, finding))
else:
merge_into(duplicate, lane, finding)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Coalesce every group bridged by a finding

When two same-cause groups are initially non-overlapping and a later finding overlaps both, this next expression merges the bridge into only the first group; its expanded range can then overlap the second group without any consolidation pass. I reproduced results containing (1–5) and (5–6) groups with identical root causes after findings (1–2), (5–6), and (2–5) arrived in that order. The report consequently assigns two IDs to one defect and splits occurrences and evidence, so selected remediation can target the same issue twice. Merge all matching groups and consolidate them transitively, with order-permutation coverage for the bridge case.

AGENTS.md reference: AGENTS.md:L12-L12

Useful? React with 👍 / 👎.

@choi138 choi138 added the 🤖 codex: needs work Codex raised issues on the current PR head that still need work label Aug 3, 2026
Close the six open Codex findings at the invariant level rather than at each
reported case, and record the boundary those invariants defend.

- Resolve git and the review binary from the platform default path, and narrow
  PATH before any external command runs.
- Override repository-configured content filters, textconv, external diff,
  core.fsmonitor, core.hooksPath, and lazy fetch, or refuse the scope.
- Derive workspace confinement from a filesystem walk that validates every
  symbolic link target, so ignore rules and index modes cannot hide a path.
- Apply the excluded-path scan to base and commit scopes, not only uncommitted.
- Pass the repository root as NUL-terminated data to preserve exact names.
- Reject NUL in finding paths, and require the baseline lane to stay always-on.
- Group findings with order-independent connected components so a bridging
  finding coalesces every matching group.

Document the untrusted inputs, enforced invariants, and non-goals in SKILL.md,
and count externally triggered rounds against the re-review bound.
@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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (3)
.agents/skills/codex-review-loop/tests/test_runner_contract.py (1)

105-117: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

use_default_codex=True일 때 상속된 TOKI_REVIEW_CODEX_BIN을 제거하십시오.

environmentos.environ.copy()로 시작합니다. 상위 환경에 TOKI_REVIEW_CODEX_BIN이 설정되어 있으면 use_default_codex=True에서도 그 값이 상속됩니다. 그 값이 존재하지 않는 경로를 가리키면 러너는 PATH 해석 로직에 도달하기 전에 exit 2를 반환합니다. test_rejects_repository_local_codex_from_path는 그 경우에도 통과하지만 검증 대상 로직을 실제로 시험하지 않습니다.

♻️ 제안된 수정
         environment = os.environ.copy()
         if not use_default_codex:
             environment["TOKI_REVIEW_CODEX_BIN"] = str(self.fake_codex)
+        else:
+            environment.pop("TOKI_REVIEW_CODEX_BIN", None)
         environment["TOKI_REVIEW_CAPTURE_FILE"] = str(self.capture)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.agents/skills/codex-review-loop/tests/test_runner_contract.py around lines
105 - 117, Update run_runner so use_default_codex=True removes any inherited
TOKI_REVIEW_CODEX_BIN from the copied environment before invoking the runner;
retain the fake-codex override when use_default_codex is false and preserve
explicit environment_overrides handling.
.agents/skills/codex-review-loop/scripts/review_git_process.py (1)

144-160: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

resolved 할당과 relative_to 검사를 분리하십시오.

현재 try 블록은 Path(entry).resolve()resolved.relative_to(...)를 함께 감쌉니다. except ValueError 본문은 resolved를 참조합니다. Path(entry).resolve()ValueError를 발생시키면 resolved는 미할당 상태이며, 핸들러가 UnboundLocalError로 실패합니다. 환경 변수에는 NUL 바이트가 들어갈 수 없으므로 현재 도달 가능성은 낮습니다. 그래도 두 단계를 분리하면 의도가 명확해지고 향후 리팩터링에 안전합니다.

또한 저장소 내부 항목을 제외하는 로직이 "예외가 발생하지 않으면 아무 것도 하지 않는다"라는 암묵적 흐름에 의존합니다. 명시적 조건으로 바꾸면 가독성이 좋아집니다.

♻️ 제안 리팩터
-    for entry in candidate_path.split(os.pathsep):
-        if not entry or not Path(entry).is_absolute():
-            continue
-        try:
-            resolved = Path(entry).resolve()
-            resolved.relative_to(repo.resolve())
-        except ValueError:
-            if str(resolved) not in safe_path_entries:
-                safe_path_entries.append(str(resolved))
-        except OSError:
-            continue
+    repo_root = repo.resolve()
+    for entry in candidate_path.split(os.pathsep):
+        if not entry or not Path(entry).is_absolute():
+            continue
+        try:
+            resolved = Path(entry).resolve()
+        except (OSError, ValueError):
+            continue
+        if resolved == repo_root or repo_root in resolved.parents:
+            continue
+        if str(resolved) not in safe_path_entries:
+            safe_path_entries.append(str(resolved))
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.agents/skills/codex-review-loop/scripts/review_git_process.py around lines
144 - 160, In the PATH sanitization loop around safe_path_entries, separate
Path(entry).resolve() from the resolved.relative_to(repo.resolve()) check so the
exception handler never references an unassigned resolved value. Explicitly skip
resolved paths inside the repository, and append only resolved paths outside it,
while continuing to ignore OSError failures.
.agents/skills/codex-review-loop/tests/test_scope_security.py (1)

566-635: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

semantic 바이트 한도 상수를 import하여 픽스처 크기를 계산하십시오.

이 테스트들은 87_381, 69_230, 350_000, 900_000 같은 하드코딩된 반복 횟수를 사용합니다. 이 값들은 review_scope_git.MAX_SEMANTIC_TOTAL_BYTES에 암묵적으로 결합되어 있습니다. 한도 상수를 변경하면 테스트가 실패하지만, 실패 원인이 크기 계산 때문인지 로직 회귀 때문인지 구분하기 어렵습니다.

상수를 import하여 필요한 크기를 계산하면 의도가 드러나고 상수 변경에 자동으로 적응합니다.

♻️ 제안 리팩터 예시
     def test_large_untracked_file_activates_specialists_conservatively(self) -> None:
         notes = self.repo / "docs" / "large.md"
         notes.parent.mkdir()
+        line = "ordinary text\n"
+        line_count = (review_scope_git.MAX_SEMANTIC_TOTAL_BYTES // len(line)) + 1
         notes.write_text(
-            ("ordinary text\n" * 87_381) + "MainActor\n",
+            (line * line_count) + "MainActor\n",
             encoding="utf-8",
         )
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.agents/skills/codex-review-loop/tests/test_scope_security.py around lines
566 - 635, Import review_scope_git.MAX_SEMANTIC_TOTAL_BYTES and replace the
hardcoded fixture repetition counts and binary payload size in the affected
tests with calculations derived from that limit, preserving each test’s intended
over-budget behavior while making the fixture sizing adapt automatically when
the limit changes.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.agents/skills/codex-review-loop/scripts/lane_registry_validation.py:
- Around line 62-67: validate_registry_contract()에서 prompt_path의 Path.resolve()
호출을 try 블록 안으로 이동하고 RuntimeError를 기존 RegistryError 변환 대상에 추가하세요. 또한
resolve_review_scope.py의 load_registry()에서도 레지스트리 경로 resolve() 중 발생하는
RuntimeError를 ScopeError로 변환해 심볼릭 링크 루프가 내부 예외로 누출되지 않도록 하세요.

---

Nitpick comments:
In @.agents/skills/codex-review-loop/scripts/review_git_process.py:
- Around line 144-160: In the PATH sanitization loop around safe_path_entries,
separate Path(entry).resolve() from the resolved.relative_to(repo.resolve())
check so the exception handler never references an unassigned resolved value.
Explicitly skip resolved paths inside the repository, and append only resolved
paths outside it, while continuing to ignore OSError failures.

In @.agents/skills/codex-review-loop/tests/test_runner_contract.py:
- Around line 105-117: Update run_runner so use_default_codex=True removes any
inherited TOKI_REVIEW_CODEX_BIN from the copied environment before invoking the
runner; retain the fake-codex override when use_default_codex is false and
preserve explicit environment_overrides handling.

In @.agents/skills/codex-review-loop/tests/test_scope_security.py:
- Around line 566-635: Import review_scope_git.MAX_SEMANTIC_TOTAL_BYTES and
replace the hardcoded fixture repetition counts and binary payload size in the
affected tests with calculations derived from that limit, preserving each test’s
intended over-budget behavior while making the fixture sizing adapt
automatically when the limit changes.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 4cbb38db-0672-455a-81b8-7877989d7214

📥 Commits

Reviewing files that changed from the base of the PR and between 83e133d and 457973a.

📒 Files selected for processing (16)
  • .agents/skills/codex-review-loop/SKILL.md
  • .agents/skills/codex-review-loop/scripts/finding_grouping.py
  • .agents/skills/codex-review-loop/scripts/finding_validation.py
  • .agents/skills/codex-review-loop/scripts/lane_registry_validation.py
  • .agents/skills/codex-review-loop/scripts/merge_findings.py
  • .agents/skills/codex-review-loop/scripts/resolve_repo_root.py
  • .agents/skills/codex-review-loop/scripts/resolve_review_scope.py
  • .agents/skills/codex-review-loop/scripts/review_git_process.py
  • .agents/skills/codex-review-loop/scripts/review_path_matching.py
  • .agents/skills/codex-review-loop/scripts/review_scope_git.py
  • .agents/skills/codex-review-loop/scripts/review_workspace.py
  • .agents/skills/codex-review-loop/scripts/run_review_lane.sh
  • .agents/skills/codex-review-loop/tests/test_finding_merge.py
  • .agents/skills/codex-review-loop/tests/test_runner_contract.py
  • .agents/skills/codex-review-loop/tests/test_scope_routing.py
  • .agents/skills/codex-review-loop/tests/test_scope_security.py
🚧 Files skipped from review as they are similar to previous changes (2)
  • .agents/skills/codex-review-loop/scripts/finding_validation.py
  • .agents/skills/codex-review-loop/scripts/resolve_review_scope.py

Comment on lines +62 to +67
prompt_path = (skill_dir / prompt).resolve()
try:
prompt_path.relative_to(lanes_dir)
prompt_path.read_text(encoding="utf-8")
except (OSError, UnicodeError, ValueError) as error:
raise RegistryError(f"{lane_id}.prompt is not a readable lane prompt") from error

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

tmp="$(mktemp -d)"
trap 'rm -rf "$tmp"' EXIT

mkdir -p "$tmp/references/lanes"
ln -s "b.md" "$tmp/references/lanes/a.md"
ln -s "a.md" "$tmp/references/lanes/b.md"

python3 - "$tmp" <<'PY'
from pathlib import Path
import sys

path = Path(sys.argv[1]) / "references" / "lanes" / "a.md"
try:
    path.resolve()
except RuntimeError:
    print("symlink-loop resolution raises RuntimeError")
else:
    raise SystemExit("expected RuntimeError")
PY

rg -n -C 5 'resolve\(\)' \
  .agents/skills/codex-review-loop/scripts/lane_registry_validation.py \
  .agents/skills/codex-review-loop/scripts/resolve_review_scope.py

Repository: choi138/toki

Length of output: 6353


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

python3 - <<'PY'
import sys

if sys.version_info < (3, 9):
    print("python_version", sys.version)
    print("sys.argv", sys.argv)
else:
    print("python_version", sys.version)
    print("sys.argv", sys.argv)
    print("sys.version_info.minor", sys.version_info.minor)
PY

sed -n '1,90p' .agents/skills/codex-review-loop/scripts/lane_registry_validation.py
sed -n '55,95p' .agents/skills/codex-review-loop/scripts/resolve_review_scope.py

Repository: choi138/toki

Length of output: 4411


Path.resolve()RuntimeError도 경로 검증 예외로 처리하세요.

prompt_path = (skill_dir / prompt).resolve()try 블록 밖에 있으므로, 심볼릭 링크 루프가 있는 lane.promptRegistryError 대신 누출되는 RuntimeError로 끝날 수 있습니다. validate_registry_contract()RuntimeError 처리도 추가하고, resolve_review_scope.pyload_registry()Path.resolve() 호출 오류를 ScopeError로 변환하세요.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.agents/skills/codex-review-loop/scripts/lane_registry_validation.py around
lines 62 - 67, validate_registry_contract()에서 prompt_path의 Path.resolve() 호출을
try 블록 안으로 이동하고 RuntimeError를 기존 RegistryError 변환 대상에 추가하세요. 또한
resolve_review_scope.py의 load_registry()에서도 레지스트리 경로 resolve() 중 발생하는
RuntimeError를 ScopeError로 변환해 심볼릭 링크 루프가 내부 예외로 누출되지 않도록 하세요.

@choi138
choi138 merged commit 3121498 into main Aug 4, 2026
9 checks passed
choi138 added a commit that referenced this pull request Aug 4, 2026
Pick up the lane-based Codex review loop from #68 so the skill files are
tracked here instead of lingering as a stale untracked copy.
@choi138
choi138 deleted the feature/codex-review-loop branch August 4, 2026 07:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🤖 codex: needs work Codex raised issues on the current PR head that still need work

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant