Skip to content

finding(objectql): with retention + ttl + archive all declared, only the ttl cutoff bounds the hot store #10527

Description

@os-elon

Recorded while implementing #10347 and deliberately left undecided by that diff, which says so in a comment at the site.

The shape

LifecycleSchema accepts all three together: retention and ttl are both bounding policies, and the archive.after === retention.maxAge refine is satisfied when the two match. For example:

{class: 'audit',retention: {maxAge: '90d'},ttl: {field: 'expires_at',expireAfter: '30d'},archive: {after: '90d',to: 'datalake'},}

reapObject short-circuits into archiveObject for any object declaring archive, so the Archiver's candidate read is the only selection that happens.

So the count of inert keys on this triple is unchanged at one — which one is inert has swapped. #10347's ruling was about the pair ttl + archive and is silent on the triple; the fix implements exactly the ruled option rather than inventing semantics for a shape nobody in this repo declares (censused: sys_audit_log and sys_metadata_audit are the only archive-declaring objects and both are retention + archive, no ttl).

The dispositions, for triage

  1. Union the two windows — a row is due when either the age bound or the ttl cutoff says so, which is exactly how the Reaper treats two declared policies on a non-archive object (both reaps run, effects union). It costs an $or in the Archiver's candidate read, issued at a driver's find rather than through the engine, and makes LifecycleSweepEntry.cutoff ambiguous (two cutoffs, one field).
  2. Refuse the triple at parse time, or require ttl.expireAfter to line up with archive.after the way retention.maxAge must. This narrows the acceptance face (Clause ②) and lives in packages/spec.
  3. Leave it, on the ground that nothing declares the triple and an author who writes both bounds beside archive most likely means the per-row one. Then say so where an author can read it — the archive.after doc currently promises "rows older than this are copied to the archive datasource before hot deletion", with no hint that a sibling ttl displaces it.

No measured business pull behind any of them: zero objects in this repo, in examples/, or in the docs declare the triple. Filed so the choice is made deliberately rather than inherited from whichever branch ran last.

Metadata

Metadata

Assignees

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions