feat(intl-pipeline): iterative patches and incremental reviews#18043
Merged
Conversation
Co-Authored-By: wackerow <54227730+wackerow@users.noreply.github.com>
- Deprecate old banner, convert TranslationBannerLegal to TranslationBanner - Utilize doNotTranslatePaths list from intl-pipeline for display boolean logic - Remove dead code from BaseLayout Co-Authored-By: wackerow <54227730+wackerow@users.noreply.github.com>
Excluded-list paths are now logged and filtered rather than failing the job. Hard validation errors still throw. Job aborts only if every target path is excluded. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> Co-Authored-By: wackerow <54227730+wackerow@users.noreply.github.com>
Adds normalizeTargetPath: strips accidental translations/<locale>/ and src/intl/<non-en>/ prefixes, auto-prefixes JSON with src/intl/en/ and markdown with public/content/, and tolerates leading "./" or "/". Resolution is now normalize -> exists-check -> validate -> excluded-skip, failing early if any target is missing on disk. log() gains an optional level arg ("log" | "warn" | "error") so Netlify output is consistently tagged.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Co-Authored-By: wackerow <54227730+wackerow@users.noreply.github.com>
- Moves DO_NOT_TRANSLATE_PATHS to constants (updates casing), where no unrelated env vars will throw errors - Update local storage key name, including usage of pathname -- removes use of `/en/` prefix and Posix - Fixes "return early" logic Co-Authored-By: wackerow <54227730+wackerow@users.noreply.github.com>
/review-translations now defaults to the open PR for intl/pending-dev and reviews only files changed since the last LLM review (read from each PR Review's GitHub-attached commit_id). Pass --full to override and re-review the entire PR. Reviews are submitted via gh pr review --comment, escalating to --approve only when zero critical issues remain. CI workflow updated to match: drops --scope input, adds --full, switches from gh pr comment to gh pr review, aligns trigger with intl/pending- branch naming. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> Co-Authored-By: wackerow <54227730+wackerow@users.noreply.github.com>
✅ Deploy Preview for ethereumorg ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
Member
|
TO FIX:
|
Adds Phase 4b: a dedicated pass that translates the values of translatable JSX attributes (title, description, alt, aria-label, etc.) on JSX components in markdown content. Restores behavior that regressed when the old i18n/ tree was removed (a110822) and its leftover gemini.ts attribute helpers were stripped as "dead code" (7f244df). The pipeline architecture had remained set up for it -- TRANSLATABLE_ATTRIBUTES list, normalizer emits component-attribute leaves, deterministic apply path -- but no orchestration drove the leaves through an LLM. The pass is self-healing: only sends leaves to the LLM whose English value still appears verbatim in the locale file, so re-runs are no-ops on already-translated attrs. Failures throw and skip manifest stamping per spec's "do no harm" partial-failure rule. Adds a temporary `force_attrs` workflow input (FORCE_ATTRS env) to backfill files in intl/pending-dev that were translated before this pass existed. Self-removable once those files are backfilled. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> Co-Authored-By: wackerow <54227730+wackerow@users.noreply.github.com>
…icals The standalone sanitizer step pointed to src/scripts/i18n/sanitize-pr.ts (deleted in the i18n-to-intl-pipeline migration). Sanitization now runs as part of the intl-pipeline translation phase, so a separate sanitizer call here is redundant. Removed the step entirely -- review focuses on reviewing. Adds an explicit note that reporting zero critical issues is acceptable. Counters the asymmetric-reward failure mode where agents fabricate criticals to "show their work." Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> Co-Authored-By: wackerow <54227730+wackerow@users.noreply.github.com>
The flag served its one-shot purpose: backfilling JSX attribute translations on files in intl/pending-dev that pre-dated the Phase 4b pass. Backfill is complete (PR #18051 merged into pending). Going forward, normal pipeline runs handle attribute translation correctly via the self-healing filter, and the flag has no remaining use. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> Co-Authored-By: wackerow <54227730+wackerow@users.noreply.github.com>
Bengali (and likely other indic locales) was getting native-script numerals (১২৩) from Gemini despite the existing rule. Strengthens the indic and cyrillic group rules to "ALWAYS" with explicit script examples, and adds the same rule to the JSX attribute prompt (which had no numeral guidance). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> Co-Authored-By: wackerow <54227730+wackerow@users.noreply.github.com>
Translations containing the same quote character as the surrounding attribute (e.g. an Arabic title="..." whose value quotes an English phrase) produced invalid JSX. Now escapes inner double-quotes to " in double-quoted attrs and inner single-quotes to ' in single-quoted attrs. Also handles single-quoted source attrs in both the self-healing filter and the apply path. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> Co-Authored-By: wackerow <54227730+wackerow@users.noreply.github.com>
wackerow
approved these changes
Apr 28, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Summary
TranslationBannerconsolidation: deprecates the old "translation out of date" banner (no longer needed now that the intl-pipeline keeps content current) and renames the English-only-pages banner fromTranslationBannerLegaltoTranslationBanner-- one banner, wired to the do-not-translate list./review-translations(CLI + GitHub Action): default scope is "files changed since the last LLM review on this PR," computed from each PR Review's GitHub-attachedcommit_id. Reviews are now submitted as proper PR Reviews (not issue comments) so the SHA travels for free.Pipeline / config changes
intl-pipeline/config.ts,intl-pipeline/main.ts: hard validation now only throws on truly invalid paths (translations/, non-en intl/); excluded-list matches are logged and filtered, only failing if the entire batch is excluded.normalizeTargetPathstrips accidentalpublic/content/translations/<locale>/andsrc/intl/<non-en>/prefixes, auto-prefixes JSON withsrc/intl/en/and markdown withpublic/content/, tolerates leading./and/.log()output for Netlify.DO_NOT_TRANSLATE_PATHSmoved tointl-pipeline/constants.tsso the banner can consume it without dragging in env-var initialization side effects.TranslationBanner
TranslationBannerLegal->TranslationBanner(single component now). Wired toDO_NOT_TRANSLATE_PATHS, with localStorage key and pathname handling cleaned up (no/en/prefix in the key, fixed return-early)./review-translations changes (CLI + CI)
intl/pending-dev(was: branch sniffing).last_review.commit_id...PR_HEADfrom the most recent submitted PR Review whose body looks like a translation review (no author filter, since reviews may be posted under either Claude's or a maintainer's GitHub identity when run locally).--fullflag (CLI + workflow_dispatch input + comment regex) overrides incremental and re-reviews the full PR diff.gh pr review --comment(or--approveonly when zero critical issues remain; never--request-changes).**Fixes:**line in the review body:Critical fixes applied: N/No fixes applied (review-only)/No critical issues found.intl/pending-head ref).Test plan
/review-translationswith no args → finds open PR forintl/pending-dev, scope-resolves correctly when no prior review exists (full PR diff)./review-translations --full→ ignores prior review SHA.@claude /review-translationsfrom an authorized PR comment fires the workflow, posts a PR Review (visible in the "Reviews" tab, not "Conversation"),commit_idis attached./style-guide/→ job continues and skips that file (rather than aborting), other files translate normally.developers/docs/blocks/index.md(no prefix) → normalization logs[pipeline] Normalizing "..." -> "public/content/..."and proceeds.Update
Phase 4b: dedicated JSX attribute translation pass for
.mdfiles. Translatable attributes (title,description, etc.) were not being translated -- regression from when the old i18n/ tree was removed. The architecture was already set up; just needed the orchestration. Self-healing filter ensures re-runs are no-ops.Also fixed:
"/'.Spec:
PIPELINE-SPEC.mdPhase 4b. Tests:jsx-attribute-translator.spec.ts.