fix(knowledge): resume the member resurrection walk from a persisted cursor

Merged
WA
1mo ago
+29536-28

Summary

  • The member resurrection pass walked a connector's documents from the first id on every run. A walk the deadline cut short never reached the tail, so documents past that point could stay tombstoned indefinitely
  • walkReconciliationWindows now takes startAfterId and returns { finished, lastId }. The resurrection pass resumes from a new nullable column, knowledge_connector.member_resurrection_cursor, and clears it once the tail is covered. The cursor is written once per run, only when it moved, under the member lease
  • It's a separate column rather than a reuse of member_tombstone_cursor, so an app rollback never misreads a resurrection position as a tombstone cursor
  • Purge still waits for a finished walk. Purge candidates have no observation and resurrectable documents do, so the two sets never overlap
  • withoutSecret strips the new column like the tombstone cursor
  • Migration: a single nullable ADD COLUMN with no default and no rewrite. It will be renumbered against #8335 at merge
  • Responds to a review thread on #8356

Type of Change

  • Bug fix

Testing

  • New integration test (real Postgres): a deadline-cut first run persists the cursor at the last handled id, the resumed run covers exactly the remaining tail, and it clears the cursor. The test fails on the pre-fix code
  • Type-check, check:migrations, and the schema-mock check pass

Checklist

  • Code follows project style guidelines
  • Self-reviewed my changes
  • Tests added/updated and passing
  • No new warnings introduced
  • I confirm that I have read and agree to the terms outlined in the Contributor License Agreement (CLA)