You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit e98fb14
Browse filesBrowse the repository at this point in the historyBrowse files
* fix(service-queue,platform-objects): bound sys_job_queue — completed rows expire on a declared ADR-0057 retention (#5179)
DbQueueAdapter marked delivered messages `completed` and nothing ever touched
the row again: `purge()` had zero production callers, `purgeFailed()` is a
manual dead-letter API, and the object declared no lifecycle policy — so the
queue table only ever grew (one permanent row per queued email since #5160).
sys_job_queue now declares `lifecycle: { class: 'transient', retention:
{ maxAge: '7d', onlyWhen: { status: 'completed' } } }`, enforced by the one
platform-owned LifecycleService reaper (ADR-0057 §3.3) on its existing hourly
sweep — no new sweeper in the adapter's poll loop, no new configuration.
`pending`/`running` (live work) and `failed`/`dlq` (the dead-letter queue) are
never swept at any age.
The dedup window becomes an enforced invariant rather than a coincidence:
publish dedups terminal rows by `created_at` against `idempotencyWindowMs`, the
reaper cuts off on the same axis, and DbQueueAdapter now reads the declared
window (`completedRetentionWindowMs()`) and throws at construction if the
idempotency window is configured longer than it.
`class: 'transient'` and not `telemetry`: per ADR-0057 §3.6 a
telemetry/event/audit class relocates the table to the dedicated `telemetry`
datasource wherever one is registered, and moving a live work queue's storage
would be a migration, not a cleanup.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017MCKJaEomEqg4tvz4SzdNd
* test(service-queue): pin the retention fake engine's delete() to ObjectQL's own dispatch (#4550)
`check:engine-double-contract` flagged the new fake engine in
job-queue-retention.test.ts: its `delete()` hand-mirrored the engine's guard
(`if (opts?.where?.id == null) throw`) instead of routing through
`assertEngineDeleteDispatch`. A mirror is looser than the producer on exactly
the shape a copy always drops — `where: { id: { $in: [...] } }` reads as an id
and is a multi-row predicate the real engine rejects without `multi` — and a
double looser than the engine it stands in for is how #4434 shipped a dead REST
route with its suite green.
Routes through the producer's predicate, same shape as the other 14 pinned
doubles, and adds the `@objectstack/objectql` devDependency the import needs
(the precedent set in plugin-email by b169f21, and in plugin-approvals /
plugin-sharing before it).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017MCKJaEomEqg4tvz4SzdNd
---------
Co-authored-by: Claude <noreply@anthropic.com>
0 commit comments