fix(sync): acknowledge auto-skipped failures (#3829) (#3891)

Wave-assembled from PR #3891 by @RerankerGuo. Conflict resolution: KEY_FILES.md
kept master's newer migrate-engine/import-file/sync entries; the PR's 3-state
machine wording re-applied onto master's sync-failure-ledger entry.

Co-Authored-By: RerankerGuo <121015044+RerankerGuo@users.noreply.github.com>
This commit is contained in:
test
2026-08-13 12:18:13 -07:00
committed by Sina Matian
co-authored by RerankerGuo
parent 136fc109c1
commit fd0e371d5b
3 changed files with 26 additions and 7 deletions
+20 -1
View File
@@ -2,7 +2,7 @@
* issue #1939 — sync failure ledger + bounded auto-skip valve.
*
* Covers the correctness gates the /codex outside-voice review identified:
* #1 auto-skipped entries stay UNRESOLVED (doctor WARN), not hidden
* #1 auto-skipped entries stay UNRESOLVED (doctor WARN) until explicit ack
* #2 (source_id, path) keying — failures never merge across sources
* #3 `<head>` sentinel never auto-skips; always hard-blocks
* #4 success clears a path so `attempts` is truly consecutive
@@ -65,6 +65,25 @@ describe('#2 multi-source keying', () => {
expect(rows.find(r => r.source_id === 'alpha')!.state).toBe('acknowledged');
expect(rows.find(r => r.source_id === 'beta')!.state).toBe('open');
});
test('acknowledgeFailures resolves auto-skipped rows for that source (#3829)', async () => {
const {
recordFailures,
autoSkipFailures,
acknowledgeFailures,
loadSyncFailures,
} = await L();
recordFailures('alpha', [{ path: 'a.md', error: 'YAML parse failed' }], 'c1');
recordFailures('beta', [{ path: 'b.md', error: 'YAML parse failed' }], 'c1');
autoSkipFailures('alpha', ['a.md']);
autoSkipFailures('beta', ['b.md']);
const result = acknowledgeFailures('alpha');
expect(result.count).toBe(1);
const rows = loadSyncFailures();
expect(rows.find(r => r.source_id === 'alpha')!.state).toBe('acknowledged');
expect(rows.find(r => r.source_id === 'beta')!.state).toBe('auto_skipped');
});
});
describe('#4 success clears → consecutive attempts', () => {