Skip to content

Commit aab9062

Browse files
igerberclaude
andcommitted
Expand block-start to all list markers, mirror include-files confinement
P1: _BLOCK_START now accepts *, +, and numbered list prefixes (1., 2.) in addition to - bullets. Prevents parse_uncertain=False on common Markdown list formats like "1. Severity: P1" or "* **Severity:** P1". P2: Step 3c --include-files scan now mirrors the script's absolute-path rejection and realpath repo-root containment check before scanning. P2: Add 3 regression tests: numbered-list severity parsing, starred-bold severity parsing, numbered-bold uncertainty detection. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent d8a520e commit aab9062

3 files changed

Lines changed: 37 additions & 7 deletions

File tree

.claude/commands/ai-review-local.md

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -172,12 +172,19 @@ if [ "$context_level" = "deep" ]; then
172172
upload_scan_files=$(find diff_diff -name "*.py" -not -path "*/__pycache__/*" 2>/dev/null | sort -u)
173173
fi
174174

175-
# Category 3: --include-files (resolve paths same as script does)
175+
# Category 3: --include-files (mirror script's path confinement)
176176
if [ -n "$include_files" ]; then
177+
repo_root_real=$(pwd -P)
177178
for f in $(echo "$include_files" | tr ',' ' '); do
178-
if [ -f "diff_diff/$f" ]; then upload_scan_files="$upload_scan_files diff_diff/$f"
179-
elif [ -f "$f" ]; then upload_scan_files="$upload_scan_files $f"
179+
# Reject absolute paths (mirrors script's os.path.isabs check)
180+
case "$f" in /*) continue ;; esac
181+
if [ -f "diff_diff/$f" ]; then candidate="diff_diff/$f"
182+
elif [ -f "$f" ]; then candidate="$f"
183+
else continue
180184
fi
185+
# Verify within repo root (mirrors script's realpath containment)
186+
real_candidate=$(cd "$(dirname "$candidate")" && pwd -P)/$(basename "$candidate")
187+
case "$real_candidate" in "$repo_root_real"/*) upload_scan_files="$upload_scan_files $candidate" ;; esac
181188
done
182189
fi
183190

.claude/scripts/openai_review.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -489,11 +489,14 @@ def write_review_state(
489489
json.dump(state, f, indent=2)
490490

491491

492+
# Match optional Markdown list prefix: -, *, +, or numbered (1., 2., etc.)
493+
_LP = r"^(?:[-*+]|\d+\.?)?\s*"
494+
492495
_BLOCK_START = re.compile(
493-
r"^-?\s*\*\*(P[0-3])\*\*" # - **P1** summary
494-
r"|^-?\s*\*\*Severity:\*\*\s*(P[0-3])" # - **Severity:** P1
495-
r"|^-?\s*\*\*Severity:\s*(P[0-3])\*\*" # - **Severity: P1**
496-
r"|^-?\s*Severity:\s*`?(P[0-3])`?" # - Severity: P1
496+
_LP + r"\*\*(P[0-3])\*\*" # - **P1**, 1. **P1**, * **P1**
497+
r"|" + _LP + r"\*\*Severity:\*\*\s*(P[0-3])" # - **Severity:** P1
498+
r"|" + _LP + r"\*\*Severity:\s*(P[0-3])\*\*" # - **Severity: P1**
499+
r"|" + _LP + r"Severity:\s*`?(P[0-3])`?" # 1. Severity: P1
497500
)
498501

499502
_IMPACT_PATTERN = re.compile(r"(?:\*\*)?Impact:(?:\*\*)?\s*(.+)")

tests/test_openai_review.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -881,8 +881,28 @@ def test_parses_bold_severity_format(self, review_mod):
881881
review_text = "**P1** Missing NaN guard in `foo.py:L10`\n"
882882
findings, _ = review_mod.parse_review_findings(review_text, 1)
883883
assert len(findings) == 1
884+
885+
def test_parses_numbered_list_severity(self, review_mod):
886+
"""1. Severity: P1 format should be parsed."""
887+
review_text = "1. Severity: P1 — Missing NaN guard in `foo.py:L10`\n"
888+
findings, _ = review_mod.parse_review_findings(review_text, 1)
889+
assert len(findings) == 1
884890
assert findings[0]["severity"] == "P1"
885891

892+
def test_parses_starred_bold_severity(self, review_mod):
893+
"""* **Severity:** P1 format should be parsed."""
894+
review_text = "* **Severity:** P1 — Missing NaN guard in `bar.py:L5`\n"
895+
findings, _ = review_mod.parse_review_findings(review_text, 1)
896+
assert len(findings) == 1
897+
assert findings[0]["severity"] == "P1"
898+
899+
def test_numbered_bold_severity_triggers_uncertainty(self, review_mod):
900+
"""1. **Severity:** P1 with no parseable summary → uncertain=True."""
901+
review_text = "1. **Severity:** P1\n"
902+
findings, uncertain = review_mod.parse_review_findings(review_text, 1)
903+
assert findings == []
904+
assert uncertain
905+
886906
def test_parses_bold_label_format(self, review_mod):
887907
"""**Severity:** P1 format should be parsed."""
888908
review_text = "- **Severity:** P1 — Missing NaN guard in `foo.py:L10`\n"

0 commit comments

Comments
 (0)