Commit 023dad4
* docs: add translation image stabilization specification for issue #137
This specification document addresses the problem of expiring Notion/S3 image
URLs in translated documentation. It provides:
- Technical analysis of the current translation pipeline
- Proposed solution integrating existing image processing infrastructure
- Detailed 5-phase implementation plan with time estimates
- Testing requirements and acceptance criteria
- Risk analysis and rollback strategy
The solution reuses the existing processAndReplaceImages() and
validateAndFixRemainingImages() functions from the notion-fetch pipeline
to stabilize image URLs before and after translation.
Closes #137
Co-authored-by: openhands <openhands@all-hands.dev>
* docs: add per-language image overrides and improve spec clarity
Updates to TRANSLATION_IMAGE_STABILIZATION_SPEC.md:
Per-language image overrides:
- Add section explaining default vs override behavior
- Document how translators can use localized screenshots
- Define precedence rules (language page wins, EN fallback)
- Add how-to snippet with before/after example
Pipeline improvements:
- Add language-aware source selection step in pipeline flow
- Update acceptance criteria for localized images
Technical clarifications:
- Add function contracts section with exact input/output types
- Fix line number typo (858-518 → 858-890)
- Add invariants section with grep verification commands
- Make failure policy explicit (fail page, no placeholders)
- Clarify validation catches mutated canonical paths
Testing:
- Add per-language override test case
- Require mocked network/filesystem in tests
Cleanup:
- Remove time estimates from phases
- Reuse existing slug logic (no new implementation)
- Expand out-of-scope section (no migration, no new storage)
Co-authored-by: openhands <openhands@all-hands.dev>
* docs: add review and simplified spec for translation image stabilization
- Add detailed review of original spec with 17 issues identified
- Add simplified spec that's easier to understand (ELI5 style)
- Key changes: removed redundant items, fixed fallback behavior,
clarified edge cases, added implementation details
🤖 Generated with [Qoder][https://qoder.com]
* docs: update image stabilization spec with implementation clarifications (#141)
* docs: fix spec accuracy issues found during code review
Address all issues identified in the spec review by verifying against
actual codebase:
- Fix function name to processSinglePageTranslation (not processPageTranslation)
- Fix slug helper to include page ID suffix for deterministic filenames
- Replace validateAndFixRemainingImages (warns only) with getImageDiagnostics + throw
- Add totalFailures > 0 check to fail on broken placeholder images
- Defer per-language image overrides to future enhancement (EN-only initially)
- Downgrade prompt enhancement to P2 (already 3 existing instructions)
- Fix import list (remove unused validateAndFixRemainingImages)
- Remove incorrect metrics.skippedSmallSize reference in logging
- Add Prerequisites section for EN fetch recommendation
- Document frontmatter images as out of scope
- Update review document with resolution status
https://claude.ai/code/session_01RMuRBsneMpCL1cBVLuVcmx
* docs: add implementation plan for translation image stabilization (#137)
Machine-readable implementation plan with atomic tasks, exact code
locations, dependency graph, and complete test specifications. Ready
for autonomous execution.
https://claude.ai/code/session_01RMuRBsneMpCL1cBVLuVcmx
* fix: address review feedback inconsistencies
- Fix __tests__/ path to flat path in simplified spec
- Fix title -> originalTitle variable name consistency
- Add note about invoking processSinglePageTranslation in tests
🤖 Generated with [Qoder][https://qoder.com]
* fix(spec): align SPEC with PLAN for logging and TASK-3.6
- Make diagnostic logging conditional (only log when successfulImages > 0)
- Fix TASK-3.6 label to match PLAN (Test title page bypass)
---------
Co-authored-by: Claude <noreply@anthropic.com>
* feat(translation): add image stabilization to translation workflow
Prevent expiring S3 URLs from being embedded in translated content by
processing images before translation. The workflow now:
1. Pre-stabilization: Download S3 images, save to /images/, replace URLs
2. Translate: Send stabilized markdown to translation API
3. Post-validation: Verify no S3 URLs survived translation
Key changes:
- Reorder pipeline: images → callouts → emojis (was callouts first)
- Skip canonical /images/ paths (don't re-process stable references)
- Cache stabilized markdown per source page (reuse across languages)
- Fail fast on image download failures (no broken placeholders)
- Redact sensitive params from error messages (signed URL safety)
Tested: 139 tests passed, 4 test files
* docs: remove redundant spec docs, keep only SPEC as source of truth
* fix: address review comments - deduplicate S3 detection and fix spec
- Extract detectNotionS3Urls() helper to eliminate duplicated detection logic
- Update acceptance criteria to clarify only Notion-family S3 URLs are blocked
- Allow generic (non-Notion) amazonaws URLs through as per implementation
* test: add cache edge case and dual detection tests for image stabilization
- Add tests for cache edge cases: no images, cache isolation, fallback
- Add tests for dual detection interaction scenarios
- Total tests increased from 17 to 22
* docs: remove per-language image override tests from spec
Per-language image overrides are not needed - images are added
manually after translation if needed. This resolves the last
remaining review comment.
* chore: remove completed translation image stabilization spec
The implementation is done, spec document is no longer needed.
🤖 Generated with [Qoder][https://qoder.com]
---------
Co-authored-by: openhands <openhands@all-hands.dev>
Co-authored-by: Claude <noreply@anthropic.com>
1 parent 2fbc024 commit 023dad4
File tree
8 files changed
+1340
-53
lines changed- scripts
- notion-fetch
- __tests__
- notion-translate
8 files changed
+1340
-53
lines changedLines changed: 109 additions & 2 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
56 | 56 | | |
57 | 57 | | |
58 | 58 | | |
| 59 | + | |
59 | 60 | | |
60 | 61 | | |
61 | 62 | | |
| |||
74 | 75 | | |
75 | 76 | | |
76 | 77 | | |
| 78 | + | |
| 79 | + | |
77 | 80 | | |
78 | 81 | | |
79 | 82 | | |
| 83 | + | |
80 | 84 | | |
81 | 85 | | |
82 | 86 | | |
| |||
472 | 476 | | |
473 | 477 | | |
474 | 478 | | |
| 479 | + | |
| 480 | + | |
| 481 | + | |
| 482 | + | |
| 483 | + | |
| 484 | + | |
| 485 | + | |
| 486 | + | |
| 487 | + | |
| 488 | + | |
| 489 | + | |
| 490 | + | |
| 491 | + | |
| 492 | + | |
| 493 | + | |
| 494 | + | |
| 495 | + | |
| 496 | + | |
| 497 | + | |
| 498 | + | |
| 499 | + | |
| 500 | + | |
| 501 | + | |
| 502 | + | |
| 503 | + | |
| 504 | + | |
| 505 | + | |
| 506 | + | |
| 507 | + | |
| 508 | + | |
| 509 | + | |
| 510 | + | |
| 511 | + | |
| 512 | + | |
| 513 | + | |
| 514 | + | |
| 515 | + | |
| 516 | + | |
| 517 | + | |
| 518 | + | |
| 519 | + | |
| 520 | + | |
| 521 | + | |
| 522 | + | |
| 523 | + | |
| 524 | + | |
| 525 | + | |
| 526 | + | |
| 527 | + | |
| 528 | + | |
| 529 | + | |
| 530 | + | |
| 531 | + | |
| 532 | + | |
| 533 | + | |
| 534 | + | |
| 535 | + | |
| 536 | + | |
| 537 | + | |
| 538 | + | |
| 539 | + | |
| 540 | + | |
| 541 | + | |
| 542 | + | |
| 543 | + | |
| 544 | + | |
| 545 | + | |
| 546 | + | |
| 547 | + | |
| 548 | + | |
| 549 | + | |
| 550 | + | |
| 551 | + | |
| 552 | + | |
| 553 | + | |
| 554 | + | |
| 555 | + | |
| 556 | + | |
| 557 | + | |
| 558 | + | |
| 559 | + | |
| 560 | + | |
| 561 | + | |
| 562 | + | |
| 563 | + | |
| 564 | + | |
| 565 | + | |
| 566 | + | |
| 567 | + | |
| 568 | + | |
| 569 | + | |
| 570 | + | |
| 571 | + | |
| 572 | + | |
| 573 | + | |
| 574 | + | |
| 575 | + | |
| 576 | + | |
| 577 | + | |
| 578 | + | |
475 | 579 | | |
476 | 580 | | |
477 | 581 | | |
| |||
1357 | 1461 | | |
1358 | 1462 | | |
1359 | 1463 | | |
| 1464 | + | |
1360 | 1465 | | |
1361 | 1466 | | |
1362 | 1467 | | |
| |||
1815 | 1920 | | |
1816 | 1921 | | |
1817 | 1922 | | |
| 1923 | + | |
1818 | 1924 | | |
1819 | 1925 | | |
1820 | 1926 | | |
| |||
1900 | 2006 | | |
1901 | 2007 | | |
1902 | 2008 | | |
| 2009 | + | |
1903 | 2010 | | |
1904 | 2011 | | |
1905 | 2012 | | |
| |||
2161 | 2268 | | |
2162 | 2269 | | |
2163 | 2270 | | |
2164 | | - | |
| 2271 | + | |
2165 | 2272 | | |
2166 | 2273 | | |
2167 | | - | |
| 2274 | + | |
2168 | 2275 | | |
2169 | 2276 | | |
2170 | 2277 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
304 | 304 | | |
305 | 305 | | |
306 | 306 | | |
307 | | - | |
308 | | - | |
| 307 | + | |
| 308 | + | |
| 309 | + | |
309 | 310 | | |
310 | 311 | | |
311 | | - | |
312 | | - | |
| 312 | + | |
| 313 | + | |
| 314 | + | |
| 315 | + | |
| 316 | + | |
| 317 | + | |
| 318 | + | |
| 319 | + | |
| 320 | + | |
| 321 | + | |
| 322 | + | |
| 323 | + | |
| 324 | + | |
| 325 | + | |
| 326 | + | |
| 327 | + | |
| 328 | + | |
| 329 | + | |
| 330 | + | |
| 331 | + | |
| 332 | + | |
313 | 333 | | |
314 | 334 | | |
315 | 335 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
81 | 81 | | |
82 | 82 | | |
83 | 83 | | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
84 | 88 | | |
85 | 89 | | |
86 | 90 | | |
| |||
441 | 445 | | |
442 | 446 | | |
443 | 447 | | |
| 448 | + | |
444 | 449 | | |
445 | 450 | | |
| 451 | + | |
| 452 | + | |
| 453 | + | |
| 454 | + | |
| 455 | + | |
| 456 | + | |
| 457 | + | |
| 458 | + | |
| 459 | + | |
| 460 | + | |
| 461 | + | |
446 | 462 | | |
447 | 463 | | |
448 | 464 | | |
| |||
526 | 542 | | |
527 | 543 | | |
528 | 544 | | |
| 545 | + | |
| 546 | + | |
| 547 | + | |
| 548 | + | |
| 549 | + | |
| 550 | + | |
| 551 | + | |
| 552 | + | |
529 | 553 | | |
530 | 554 | | |
531 | 555 | | |
| |||
680 | 704 | | |
681 | 705 | | |
682 | 706 | | |
| 707 | + | |
683 | 708 | | |
684 | 709 | | |
685 | | - | |
| 710 | + | |
686 | 711 | | |
687 | 712 | | |
688 | 713 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
125 | 125 | | |
126 | 126 | | |
127 | 127 | | |
128 | | - | |
129 | | - | |
| 128 | + | |
| 129 | + | |
130 | 130 | | |
131 | 131 | | |
132 | 132 | | |
| |||
200 | 200 | | |
201 | 201 | | |
202 | 202 | | |
203 | | - | |
| 203 | + | |
204 | 204 | | |
205 | 205 | | |
206 | 206 | | |
| |||
225 | 225 | | |
226 | 226 | | |
227 | 227 | | |
228 | | - | |
| 228 | + | |
229 | 229 | | |
230 | 230 | | |
231 | 231 | | |
232 | 232 | | |
233 | | - | |
| 233 | + | |
234 | 234 | | |
235 | 235 | | |
236 | 236 | | |
| |||
245 | 245 | | |
246 | 246 | | |
247 | 247 | | |
248 | | - | |
249 | | - | |
250 | | - | |
251 | | - | |
252 | | - | |
253 | | - | |
254 | | - | |
255 | | - | |
256 | | - | |
257 | | - | |
258 | | - | |
259 | | - | |
260 | | - | |
261 | | - | |
262 | | - | |
263 | 248 | | |
264 | 249 | | |
265 | 250 | | |
| |||
268 | 253 | | |
269 | 254 | | |
270 | 255 | | |
| 256 | + | |
| 257 | + | |
| 258 | + | |
| 259 | + | |
| 260 | + | |
271 | 261 | | |
272 | 262 | | |
273 | 263 | | |
| |||
549 | 539 | | |
550 | 540 | | |
551 | 541 | | |
552 | | - | |
553 | | - | |
| 542 | + | |
| 543 | + | |
554 | 544 | | |
555 | 545 | | |
556 | 546 | | |
| |||
606 | 596 | | |
607 | 597 | | |
608 | 598 | | |
609 | | - | |
610 | | - | |
611 | | - | |
612 | | - | |
613 | | - | |
614 | | - | |
615 | 599 | | |
616 | 600 | | |
617 | 601 | | |
| |||
620 | 604 | | |
621 | 605 | | |
622 | 606 | | |
| 607 | + | |
| 608 | + | |
| 609 | + | |
| 610 | + | |
| 611 | + | |
| 612 | + | |
623 | 613 | | |
624 | 614 | | |
625 | 615 | | |
| |||
0 commit comments