Replace the Phase 2 in-flight chat gate (buffered channel) with a real
SQLite-backed job queue and single worker loop. Every /api/chat request
now creates a job row, blocks until the worker completes it, and returns
the result transparently.
Key changes:
- internal/store: NextJob (drain-by-model ordering), IncrementAttempt,
ResetInterruptedJobs, DeleteTerminalJobsBefore; busy_timeout pragma
- internal/worker: single-threaded worker loop with Notifier for sync
handler completion signaling; retry on ConnectionError, terminal fail
on HTTPError; crash recovery resets interrupted jobs on startup
- internal/webhook: dispatcher infrastructure for async webhook delivery
- internal/server: chat handler rewritten to enqueue+wait; old chatGate
removed; embeddings remain direct concurrent proxies (ADR-0013)
- internal/config: FOREMAN_MAX_ATTEMPTS, FOREMAN_JOB_TTL
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Phase 1 of foreman: initialize the Go module, project layout, and core
infrastructure. Includes env-based configuration (FOREMAN_* namespace),
SQLite-backed durable job queue with WAL mode via modernc.org/sqlite,
stdlib HTTP server with /healthz and optional bearer-token auth middleware,
subcommand dispatch (serve + stubs), Gitea CI workflow, multi-stage
distroless Dockerfile, and comprehensive tests for all packages.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>