Skip to content
Open
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
33c1581
fix(translate): prevent content loss in long-form translation (#166)
luandro Mar 19, 2026
fd3b4d2
fix(translate): address Codex review — reachable 8k floor and correct…
luandro Mar 19, 2026
c36dfe9
fix(translate): count setext headings in structure metrics
luandro Mar 19, 2026
4459a15
fix(translate): restrict setext heading detection to H1 (===) only
luandro Mar 19, 2026
ecdf122
fix(translate): add setext H2 and admonition tracking to completeness…
luandro Mar 19, 2026
c67c047
fix(translate): strip fenced content before metrics and fix table det…
luandro Mar 19, 2026
ece8b76
fix(scripts): resolve typescript compilation and markdown parsing bugs
luandro Mar 19, 2026
0c418f1
fix(translate): exclude YAML frontmatter from structure metrics
luandro Mar 20, 2026
d1b5ff2
fix(translate): tolerate one missing heading and restore unclosed fen…
luandro Mar 20, 2026
a5db86f
docs: add initial CHANGELOG.md file
luandro Mar 20, 2026
b040df4
fix(translate): flag any heading loss as incomplete translation
luandro Mar 25, 2026
014bd81
fix(translate): detect finish_reason:length as token_overflow
luandro Mar 25, 2026
7168988
fix(notion-translate): harden translation integrity checks
luandro Mar 26, 2026
3252c66
fix(translate): handle indented fenced code blocks
luandro Mar 26, 2026
93ba455
fix(i18n): restore translation strings and changelog formatting
luandro Mar 26, 2026
2a5bb87
revert(i18n): remove locale files from issue-166
luandro Mar 26, 2026
23e0754
fix(translate): track CommonMark fence length to prevent nested-fence…
luandro Mar 26, 2026
d15da43
fix(translate): wire frontmatter integrity failures into chunk-halvin…
luandro Mar 26, 2026
58e0a00
fix(translate): force chunked retries after incomplete responses
luandro Mar 27, 2026
1d624e0
test(translate): add efficiency eval coverage
luandro Mar 27, 2026
8638989
perf(translate): bound custom backend output budgets
luandro Mar 27, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
129 changes: 129 additions & 0 deletions .claude/agents/context/20260325-pr-critical-reviewer-CONTEXT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
---
agent: pr-critical-reviewer
timestamp: 2026-03-25T00:00:00Z
session_id: issue-166-heading-loss-fix
prior_context: []
next_agents: []
---

# Agent Context: PR Critical Reviewer

## Mission Summary
**PR Reviewed:** Fix for heading loss tolerance in isSuspiciouslyIncompleteTranslation (issue-166)
**Review Status:** Approved
**Critical Issues:** 0

## Key Findings from Prior Context
**Expected from Spec:** N/A — no prior spec context files found
**Expected from Plan:** N/A — no prior implementation planner context found
**Actual vs Expected:** Fix matches the reviewer's stated intent

## Analysis Results
**Code Changes Reviewed:**
- Files changed: 1
- Lines changed: 1 (single operator fix)
- Complexity assessment: Low

**File reviewed:**
`/home/luandro/Dev/digidem/comapeo-docs/.worktrees/issue-166/scripts/notion-translate/translateFrontMatter.ts`
Lines 598-640 (isSuspiciouslyIncompleteTranslation function)

**Test file reviewed:**
`/home/luandro/Dev/digidem/comapeo-docs/.worktrees/issue-166/scripts/notion-translate/translateFrontMatter.test.ts`

## Fix Details

**Before:**
```typescript
const headingLoss =
sourceMetrics.headingCount > 0 &&
translatedMetrics.headingCount < sourceMetrics.headingCount - 1;
```

**After:**
```typescript
const headingLoss =
sourceMetrics.headingCount > 0 &&
translatedMetrics.headingCount < sourceMetrics.headingCount;
```

## Analysis Results

**Critical Issues Identified:** None

**Severity Breakdown:**
| Type | Count | Severity |
|------|-------|----------|
| Bugs | 0 | - |
| Security | 0 | - |
| Performance | 0 | - |
| Correctness | 0 | - |

## Edge Case Analysis

**headingCount = 0:**
Safe. The `sourceMetrics.headingCount > 0` guard on line 612 short-circuits
the entire headingLoss sub-expression to false. Zero-heading documents are
unaffected.

**headingCount = 1:**
Correct. If the source has one heading and the translation has zero, headingLoss
is now true and a retry fires. This is the right behavior — dropping the only
heading is a genuine structural loss.

**Legitimate LLM heading merging (false-positive risk):**
Low risk. If an LLM merges two headings into one, the new strict check will
trigger a retry. The retry path (lines 995-1016) uses isCritical: false and
retries with smaller chunks up to TRANSLATION_COMPLETENESS_MAX_RETRIES times.
The cost is extra API calls only; the final translation is not broken. Silent
heading loss is a more severe failure mode than a spurious retry, so the
trade-off is acceptable and consistent with the design intent for all other
structural checks in the same function.

**Consistency with sibling checks:**
fencedBlockLoss, admonitionLoss, and tableLoss all use strict zero-tolerance
comparisons. The old headingLoss tolerance of -1 was the only outlier. The fix
makes headingLoss consistent with the rest of the function.

## Test Coverage Assessment

The test "retries with smaller chunks when a valid response omits a section"
(translateFrontMatter.test.ts line 126) is the primary coverage for headingLoss.
It uses a 4-heading source and a 2-heading response.

- Old condition: 2 < (4 - 1) = 2 < 3 = true — test passed before the fix
- New condition: 2 < 4 = true — test still passes after the fix

The test remains valid. No test updates are required.

**Coverage gap (non-blocking):** There is no test that specifically covers the
boundary case the fix addresses — source with N headings, translation returning
exactly N-1 headings. This gap existed before and still exists. It is not a
blocker since the existing test exercises the core path correctly.

## Actions Taken
**Review Process:**
- Read full translateFrontMatter.ts (1044 lines)
- Read full translateFrontMatter.test.ts (572 lines)
- Analyzed isSuspiciouslyIncompleteTranslation logic and all sibling checks
- Analyzed retry/recovery path in translateText
- Verified edge cases for headingCount 0, 1, and N
- Verified test coverage adequacy

**Sub-Agents Spawned:** None — fix is approved, no fixer needed

## Recommendations

**Before Merge:**
- No blocking items

**Optional follow-up (not blocking):**
- Add a targeted unit test for the N-1 heading boundary case that was the
subject of the fix, to prevent future regressions on the exact threshold

## Handoff Notes

**For Developer:**
- Fix is correct and complete as written
- No test changes required
- Re-review not required
Loading
Loading