Skip to content

fix(ci): bound translation email scanning - #5454

Closed
luvs01 wants to merge 3 commits into
lidge-jun:devfrom
luvs01:fix/567-translation-scan-bound
Closed

luvs01 wants to merge 3 commits into
lidge-jun:devfrom
luvs01:fix/567-translation-scan-bound

Conversation

@luvs01

@luvs01 luvs01 commented Sep 21, 2026 •

Copy link
Copy Markdown
Collaborator

Motivation

  • A recent sanitizer introduced an unanchored email-local-part regex that exhibits quadratic worst-case behavior on long non-email tokens and can slow CI/workflows when processing model-produced translation output.

Description

  • Replace the global unanchored local-part email match in sanitizeTranslationBody with a pattern that begins at the literal @ (scan from each at-sign) so email masking no longer scans every suffix of long tokens.
  • Keep existing mention-defusing logic and the sentinel-based email restoration (^A -> @) so punctuation-bearing local parts still pass through unchanged.
  • Add a regression test that asserts sanitizeTranslationBody handles a 60,000-character non-email token in bounded time.

Testing

  • bun test ./.github/scripts/issue-translation.test.cjs: 70 tests pass.

Summary by CodeRabbit

  • Bug Fixes

    • Improved translation sanitization performance when processing extremely long non-email text.
    • Preserved existing masking behavior for standard email addresses while ensuring long non-email content remains unchanged.
  • Tests

    • Added coverage for processing 60,000-character non-email text within an expected time limit.

@coderabbitai

coderabbitai Bot commented Sep 21, 2026 •

Copy link
Copy Markdown
Contributor

Review Change StackReview Change Stack

Understand this PR’s impact

Explore downstream dependencies and potential security impact with Blast Radius.

View blast radius →

Important

Review skipped

Review was skipped as selected files did not have any reviewable changes.

⚙️ Run configuration

Configuration used: Repository: lidge-jun/opencodex/.coderabbit.yaml

Review profile: ASSERTIVE

Plan: Advanced

Run ID: 2c445606-2689-4991-a250-dba554f70e5b

📥 Commits

Reviewing files that changed from the base of the PR and between bc0ff54 and 16a4fcf.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository: lidge-jun/opencodex/.coderabbit.yaml

Review profile: ASSERTIVE

Plan: Advanced

Run ID: 2f42ce50-d712-4a2d-9fb2-c8848cffaf63

📥 Commits

Reviewing files that changed from the base of the PR and between 7d9fc97 and bc0ff54.

📒 Files selected for processing (1)
  • .github/scripts/issue-translation.cjs

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


📝 Walkthrough

Walkthrough

sanitizeTranslationBody now uses a lookbehind for email masking. Valid email output remains unchanged. A regression test checks bounded processing for a 60,000-character non-email token.

Changes

Email sanitization

Layer / File(s) Summary
Regex update and performance validation
.github/scripts/issue-translation.cjs, .github/scripts/issue-translation.test.cjs
The regex matches only the @domain tail after one allowed local-part character. The test verifies unchanged output and completion within 1,000 ms for a 60,000-character non-email token.

Priority: ⬇️ Low

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

Change: Bug fix

Suggested reviewers: wibias

🚥 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: bounding translation email scanning in CI. It matches the regex optimization and regression test described in the pull request.
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
🧪 Generate unit tests (beta)
  • Create a new PR

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.

@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 Sep 21, 2026
@github-actions
github-actions Bot marked this pull request as ready for review September 21, 2026 10:35
@github-actions

github-actions Bot commented Sep 21, 2026 •

Copy link
Copy Markdown
Contributor

✅ READY

  • all PR quality gates passed.

Hygiene

✅ Deterministic PR hygiene checks passed.

@lidge-jun

Copy link
Copy Markdown
Owner

리뷰 · 우선순위 18 / 80

이 PR은 이슈 번역문을 다듬는 sanitizeTranslationBody가, 이메일이 아닌 아주 긴 글에서 느려지는 문제를 고칩니다.

예전 정규식은 골뱅이(@) 앞의 이메일 이름을 최대한 길게 잡고, 뒤에 도메인이 없으면 한 글자씩 줄여 다시 봤습니다. 이름에 들어갈 글자만 6만 개 이어지고 골뱅이가 없으면, 시작 위치를 옮길 때마다 그 일이 반복됩니다. 모델이 만든 긴 번역을 CI에서 처리할 때 여기서 시간이 제곱으로 늘 수 있습니다.

새 정규식은 골뱅이를 먼저 찾습니다. 바로 앞 한 글자가 이메일 이름에 쓰이는 글자이고, 뒤에 점이 있는 도메인이 있을 때만 그 골뱅이를 잠깐 숨깁니다. 숨기는 이유는 예전과 같습니다. x!@example.com처럼 부호가 섞인 메일이 멘션으로 잘리지 않게 하고, end!@octocat처럼 점이 없는 호출은 그대로 막습니다. 기존 테스트에 있는 메일 문장과, 골뱅이만 있고 메일이 아닌 긴 글을 옛 식과 새 식으로 비교하면 결과가 같았습니다. 6만 글자 경우는 새 식이 1밀리초보다 짧게 끝났습니다.

라인 .github/scripts/issue-translation.cjs 이메일 정규식 - 느림을 없앤 방향은 맞습니다. 주석에는 아직 "이름을 길게 잡지 않고 골뱅이부터 보는 이유"가 없습니다. 나중에 예전 패턴으로 되돌리면 같은 느림이 다시 납니다.

라인 .github/scripts/issue-translation.test.cjs handles long non-email tokens in bounded time - a 6만 개에 골뱅이가 없는 경우만 1초 안에 끝나는지 봅니다. 이번에 터진 경우는 그게 맞습니다. 골뱅이는 있지만 도메인이 아닌 긴 글은 테스트에 없습니다. 도메인 쪽 길이는 63자로 막혀 있어서 같은 제곱 느림은 잘 안 나옵니다.

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

테스트의 1초 제한을 남길지입니다. 고친 코드는 6만 글자를 아주 빨리 처리해서, 평소에는 1초를 넘기기 어렵습니다. 테스트를 돌리는 컴퓨터가 다른 일로 아주 느려졌을 때만 시간 비교가 실패할 수 있습니다. 그 실패를 피하려면 시간은 재지 않고 내용이 그대로인지만 보면 됩니다. 그러면 "느리지 않다"는 증거는 약해집니다.

너의 추천

합쳐도 됩니다. 베이스는 dev이고, 고친 파일은 번역 스크립트와 테스트 둘뿐입니다. types.ts/config.ts 분할이나 닫을 중복 PR은 없습니다. 주석 한 줄("골뱅이부터 찾아서 긴 글에서 제곱으로 느려지지 않게 한다")만 보태면 충분하고, 없어도 동작은 맞습니다.

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

@luvs01

luvs01 commented Sep 21, 2026

Copy link
Copy Markdown
Collaborator Author

Review feedback applied on bc0ff540bd: the email-mask comment now records why the pattern anchors on the @ (the previous local-part-first pattern rescanned long non-email tokens once per start position - quadratic on model-generated bodies), so a future refactor does not silently reintroduce the slowdown. The 1s timing bound is kept: the fixed path finishes in ~1ms, leaving three orders of headroom for slow CI hosts. Tests: 70 pass.

@github-actions
github-actions Bot marked this pull request as draft September 21, 2026 21:40
@github-actions
github-actions Bot marked this pull request as ready for review September 22, 2026 04:24
lidge-jun added a commit that referenced this pull request Sep 22, 2026
…#5509)

* chore(dev): retire automatic pre-push validation (#5500)

Carry #5500 and align both draft enforcement prompts with scoped validation. Clarify that inherited Git override isolation belongs to the fixture harness.

Co-authored-by: JUN <243035832+lidge-jun@users.noreply.github.com>

* ci: root macOS discovery and diagnose owned process waits (#5483)

Carry the rooted sharded suite and read-only stall observer without changing control-lane batching, suite budgets, or failure propagation.

Co-authored-by: luvs01 <27862058+luvs01@users.noreply.github.com>

* test: isolate Windows runtime discovery and reservation fixtures (#5484)

Carry #5484 while avoiding the unnecessary parent LOCALAPPDATA mutation. Preserve real SQLite contention, atomic publication, reservation assertions, and existing deadlines.

Co-authored-by: luvs01 <27862058+luvs01@users.noreply.github.com>

* fix(ci): bound translation email scanning (#5454)

Carry the at-sign-anchored sanitizer scan, explanatory rationale, and long-token regression without changing mention-defusing semantics.

Co-authored-by: luvs01 <27862058+luvs01@users.noreply.github.com>

* fix(ci): redact diagnostic paths and align localized command lists

Capture and redact sample output before bounded emission, retain diagnostic child ownership and regression fixtures, and add the missing test:changed command to six locale inventories. Local runtime validation remains NOT RUN by owner instruction.

* fix(ci): preserve legacy checklist bodies with durable re-attestation

Require author clear-and-retick saves bound to real head/base and persisted server-time checkpoints. Preserve pending state across events, invalidate stale evidence, and refresh live PR and saved proof before readiness. Keep body writes out of migration handling and cover mutation failures and sequential races.

Local runtime validation: NOT RUN by owner instruction. Independent static review passed; hosted verification and explicit maintainer security review remain pending.

* fix(ci): require saved attestation evidence before readiness promotion

The pre-ready readback compared the saved gate comment with the run's
expected state, but the gate mutated the listed comment object in place,
so a readback that shared it observed this run's own write. Replace the
object instead and require the saved state to be a finalized attestation
of the live head, base and body before any ready side effect.

A wording-only save that keeps its ticks now gets a specific action, so
the rejected shortcut is acknowledged in the gate comment instead of
being skipped as a byte-identical update.

Record the readback as a reviewed read, and move the self-contained
exhaustive-deps suppression block byte for byte into a sibling file to
keep ci-workflows.test.ts under its size cap.

Local runtime validation: NOT RUN by owner instruction; hosted CI verifies.

---------

Co-authored-by: JUN <243035832+lidge-jun@users.noreply.github.com>
Co-authored-by: luvs01 <27862058+luvs01@users.noreply.github.com>
@lidge-jun

Copy link
Copy Markdown
Owner

Thanks @luvs01. The bounded translation email scanning from this PR landed on dev through #5509 (squash commit 798c07c), with a Co-authored-by trailer crediting you. Closing as superseded by that bundle.

@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