feat(lifecycle): ADR-0057 follow-ups — retire per-plugin sweepers, dev telemetry datasource + db:clean, Studio lifecycle form (#2834)#2835
Merged
Conversation
ADR-0057 §6 rejects per-plugin cleanup jobs; with the LifecycleService enforcing the same windows from the `lifecycle` declarations (sys_job_run 30d, notification pipeline 90d), the plugin-local sweepers were redundant — and worse, a window tuned via the `lifecycle.retention_overrides` setting would leave them enforcing a stale bound. - service-job: JobRunRetention (+ tests, exports, `retentionDays`/ `retentionSweepMs` options, sweep timer) removed. - service-messaging: NotificationRetention (+ tests, exports, options, sweep timer) removed. - BREAKING (ships as minor per the launch-window convention): the `retentionDays`/`retentionSweepMs` plugin options are gone. Operators who tuned them move to the `lifecycle` settings namespace (`retention_overrides`, tenant-scoped) — same knob, now runtime- and tenant-configurable. FIX shipped alongside (found during this retirement): #2791 had declared a blanket `lifecycle: { class: 'telemetry', retention: { maxAge: '30d' } }` on sys_automation_run — but that table interleaves live SUSPENDED runs (resumable workflow state; an approval may legitimately stay paused for months) with terminal history. A blanket age reap would strand in-flight approvals. The declaration is removed; bounding stays with the automation store's specialized default-on sweep (terminal statuses only, by age + per-flow cap — #2585), documented on the object. sys_automation_run's own sweeper is deliberately NOT retired: the declarative contract has no status predicate yet. launch-readiness.md P1-2 annotated as superseded by ADR-0057. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BNBzMWmSECrbiEDdVzwBt3
Telemetry separation goes live for development (ADR-0057 §3.6): when the primary datasource is a file-backed SQLite, `objectstack dev` now provisions a sibling `<primary>.telemetry.<ext>` file and registers it as the `telemetry` datasource — the engine routes every telemetry/event/audit- classed object there, so platform-generated growth can never again bloat the business dev.db. Opt out with OS_TELEMETRY_DB=0; opt in anywhere (incl. `serve`) with OS_TELEMETRY_DB=<path>. Production stays opt-in: a second file appearing next to a prod database is a topology change an operator should choose. Best-effort: a failed provision never blocks boot. New `os db clean` (ADR-0057 §3.4): auto_vacuum only changes the layout of a FRESH database, so files created before the INCREMENTAL default stay pinned at their high-water mark until one full VACUUM rebuilds them. The command sets the pragma, VACUUMs the primary (and its telemetry sibling when present), and reports reclaimed bytes. Smoke-verified: a 48.9 MB deleted-rows file compacted to 0.01 MB and read back auto_vacuum=2. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BNBzMWmSECrbiEDdVzwBt3
…#2834 ③) object.form.ts (metadata-admin form) gains a `lifecycle` composite in the Advanced section — class selector (record/audit/telemetry/transient/event) plus the retention / ttl / rotation storage / archive / reclaim sub-blocks, matching LifecycleSchema field-for-field. The four metadata-forms i18n bundles are regenerated via `os i18n extract` (new lifecycle keys; keys of long-retired form fields pruned by the same run). zh-CN carries hand-curated translations for the 16 new keys; ja-JP / es-ES keep the standard English fill pending curation. The *.objects.generated.ts bundles are deliberately NOT regenerated: the committed ones carry sys_* translations (e.g. sys_audit_log) whose objects live outside the extract config's import set, so a regen would drop curated zh-CN content — that pre-existing extract-config drift is noted on #2834 and left for its own fix. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BNBzMWmSECrbiEDdVzwBt3
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BNBzMWmSECrbiEDdVzwBt3
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Contributor
📓 Docs Drift CheckThis PR changes 5 package(s): 105 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:
|
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BNBzMWmSECrbiEDdVzwBt3
os-zhuang
marked this pull request as ready for review
July 11, 2026 09:11
This was referenced Jul 11, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Implements items ①–③ of the ADR-0057 follow-up tracking issue #2834 (④ PG-partition rotation is evaluated + design-sketched on the issue, deferred until CI has a PostgreSQL service — no unverified DDL ships).
① Retire the per-plugin retention sweepers
service-job'sJobRunRetentionandservice-messaging'sNotificationRetention(plus theirretentionDays/retentionSweepMsoptions, timers, exports, and tests) are removed — the LifecycleService enforces the same windows from thelifecycledeclarations (sys_job_run30d, notification pipeline 90d), and a window tuned vialifecycle.retention_overrideswould otherwise leave the old sweepers enforcing a stale bound. BREAKING, ships as minor per the launch-window convention; migration is the settings namespace.Includes a real fix found during the retirement: #2791 declared a blanket 30d lifecycle retention on
sys_automation_run— but that table interleaves live SUSPENDED runs (an approval may legitimately stay paused for months) with terminal history, so a blanket age reap could strand in-flight approvals. The declaration is removed; bounding stays with the automation store's specialized terminal-only sweep (#2585), which is deliberately NOT retired (the declarative contract has no status predicate yet).launch-readiness.mdP1-2 annotated as superseded.② Dev telemetry datasource +
os db cleanobjectstack devwith a file-backed SQLite primary now provisions<primary>.telemetry.<ext>and registers it as thetelemetrydatasource — the engine routes every telemetry/event/audit-classed object there, so platform data stops sharing the business dev DB.OS_TELEMETRY_DB=0opts out;OS_TELEMETRY_DB=<path>opts in anywhere (incl.serve— production stays opt-in by design). Best-effort: a failed provision never blocks boot.os db clean(ADR §3.4): setsauto_vacuum=INCREMENTALthen runs the one-timeVACUUMlegacy files need to adopt it, on the primary + telemetry sibling, reporting reclaimed bytes. Smoke-verified end-to-end: a 48.9 MB deleted-rows probe file compacted to 0.01 MB and read backauto_vacuum=2.③ Studio surface + i18n
object.form.tsgains thelifecyclecomposite (class select + retention/ttl/rotation/archive/reclaim blocks, field-for-field withLifecycleSchema); the four metadata-forms i18n bundles are regenerated (os i18n extract) with hand-curated zh-CN for the 16 new keys. The*.objects.generated.tsbundles are deliberately untouched: regenerating them would delete curated sys_* translations due to a pre-existing extract-config drift — documented on #2834.Verification
resolveTelemetryDbPathmatrix (dev default-on,:memory:skip, env opt-out/override, prod opt-in)os db cleanfunctional smoke against a real bloated SQLite fileRefs #2834.
🤖 Generated with Claude Code
https://claude.ai/code/session_01BNBzMWmSECrbiEDdVzwBt3
Generated by Claude Code