# Fix the translation agent stuck re-extracting the string catalog

## TL;DR

The agent re-extracts because it cannot tell extraction already happened, so give it a stamp file to check. Extraction and translation are separate phases, and the agent should only run extraction when sources changed. Write a catalog stamp with the source hash after extraction, and skip extraction when the stamp matches.

## The error

```text
Translation agent log: extract, translate, extract, translate...
catalog rebuilt from scratch on every loop iteration
```

## Fix it

### Step 1: Confirm extraction runs every iteration

```bash
grep -c "extracting string catalog" logs/agent.log
```

Expected: The count matches the iteration count, proving the redundancy.

### Step 2: Add a stamp file with the source hash

```bash
node -e "console.log('after extraction: write .catalog-stamp with a hash of the source file list and mtimes')"
```

Expected: The stamp records what extraction covered.

### Step 3: Skip extraction when the stamp matches

```bash
node -e "console.log('at iteration start: recompute the hash, skip extraction if it equals the stamp')"
```

Expected: Unchanged sources skip extraction.

### Step 4: Run two iterations and confirm one extraction

```bash
node scripts/translate-agent.js | grep -c "extracting string catalog"
```

Expected: The count is 1 for two iterations.

## When to use this

- A translation agent re-extracts the catalog every iteration
- Runs are slow with no source changes

## When NOT to use this

- Sources change every iteration, then extraction is correct
- The loop is in translation retries, different fix

## Tool and version compatibility

- Any phased agent: extract then translate
- File hashing for change detection

## Variant phrasings

### stamp matches but strings are stale

Your hash misses something, like config. Hash the inputs that actually affect extraction.

### agent runs extraction on purpose each time

Then the bug is the loop itself. Fix why it iterates instead of finishing.

## Why it happens

The agent's loop has no memory of completed phases, so each iteration redoes all of them. Extraction is the expensive phase, and without a completion signal the agent cannot distinguish first run from retry.

## Edge cases

- Hash file contents not just mtimes, mtimes lie across checkouts
- Delete the stamp when the extractor version changes
- Log skip vs run decisions so the behavior is visible

## Provenance

Resolved from the public thread: https://vectle.com/posts/pst_dPNV_dg9LsSfdK9-XAew4A
