Skip to content

feat(ingest): reconcile orphaned published parse_jobs (F5) - #23

Merged
Afgan0r merged 5 commits into
masterfrom
fix/f5-orphaned-jobs-reconciler
Jun 15, 2026
Merged

Afgan0r merged 5 commits into
masterfrom
fix/f5-orphaned-jobs-reconciler

Conversation

@Afgan0r

@Afgan0r Afgan0r commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

F5 — reconcile orphaned published parse_jobs

parse_jobs stuck in published were never recovered: listPublishableJobs only selects queued/retryable, so a published job whose parser result never returned was a permanent dead-end (75 orphaned on staging, oldest 33 days).

Adds a parse-job-reconciler IntervalTask that re-queues published jobs whose published_at is older than a configurable staleness threshold, so the existing publisher re-publishes them. Re-queue is idempotent (a late parser result still supersedes via parser_results); FOR UPDATE SKIP LOCKED makes concurrent replicas claim disjoint batches; every reclaim writes a reconciled parse_job_history audit row (new enum value, migration 0012).

Config: PARSE_JOB_STALE_AFTER_MS (default 1h) and PARSE_JOB_RECONCILE_BATCH_SIZE (default 25).

Scope: the parser-side root cause (ack-after-persist in replay-parser-2) is a separate change, out of scope here — this is the server-2 recovery loop only.

Tests

Factory-injection reconciler unit test + real-pg integration (stale→queued, reconciled history, fresh/queued untouched, idempotent second pass). pnpm verify green, 100% coverage.

🤖 Generated with Claude Code

Afgan0r and others added 5 commits June 15, 2026 22:33
… jobs

- Add 0012 migration introducing the 'reconciled' parse_job_history action
- Add 'reconciled' to the ParseJobHistoryAction union
- Add reclaimStalePublishedJobs repository method (FOR UPDATE SKIP LOCKED
  re-queue of stale published jobs + reconciled history row per reclaim)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…r shape

- ParseJobReconciler.reconcileStale calls reclaimStalePublishedJobs and,
  per reclaimed job, notifies the observer and logs job bindings
- Narrow ParseJobReconcilerRepository contract + noop observer/logger defaults
- Factory-injection unit test covers populated/empty/noop-default paths

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
… task

- Surface PARSE_JOB_STALE_AFTER_MS (default 1h) and
  PARSE_JOB_RECONCILE_BATCH_SIZE (default 25) on config.ingest
- createIngestRuntime constructs ParseJobReconciler and runs a third
  parse-job-reconciler IntervalTask, started/closed with the others
- server.ts passes staleAfterMs/reconcileBatchSize through
- Update runtime/app/queue/storage constructors for the new fields
- Real-pg integration: stale published -> queued re-queue + reconciled
  history, fresh/queued untouched, idempotent second pass

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…s-reconciler

# Conflicts:
#	.planning/STATE.md
@Afgan0r
Afgan0r merged commit 0fe3326 into master Jun 15, 2026
3 checks passed
@Afgan0r
Afgan0r deleted the fix/f5-orphaned-jobs-reconciler branch June 15, 2026 16:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant