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
Found while implementing #10347 (the Archiver now selects rows by the declared ttl cutoff). Out of that card's scope by its own fence, recorded rather than touched — the file is packages/spec (domain:spec lane) and reopening the refusal is explicitly a separate decision.
What goes stale
packages/spec/src/data/object.zod.ts refuses ttl.onlyWhen beside archive, and both its rationale comment and its author-facing message state the runtime fact that justified the refusal:
comment: "reapObject returns into archiveObject before the ttl reap ever runs, so with archive declared the filter guards a code path that is never executed ... while the Archiver itself copies and hot-deletes by created_at age alone"
message: "lifecycle.ttl.onlyWhen cannot be combined with archive — archive takes over the whole reap (the ttl sweep never runs) and the Archiver moves rows by age alone"
Once #10347 lands, the second half of each is false: with ttl declared the Archiver moves rows by the ttl cutoff on ttl.field, not by created_at age. An author who reads the message is told the sweep never runs, which is now wrong about their own object.
Two separable pieces
Message and comment accuracy. Whatever is decided about the refusal itself, the wording should stop asserting a runtime behaviour that no longer exists. This is text, not accept-set.
⚠️ Do not read this as an argument for either direction. #10347's ruling explicitly declined to authorize reopening the refusal; this is only the record that its stated reason has changed.
The retention.onlyWhen x archive refine beside it is unaffected: with retention and no ttl the Archiver still moves rows by created_at age.
Found while implementing #10347 (the Archiver now selects rows by the declared
ttlcutoff). Out of that card's scope by its own fence, recorded rather than touched — the file ispackages/spec(domain:speclane) and reopening the refusal is explicitly a separate decision.What goes stale
packages/spec/src/data/object.zod.tsrefusesttl.onlyWhenbesidearchive, and both its rationale comment and its author-facing message state the runtime fact that justified the refusal:reapObjectreturns intoarchiveObjectbefore the ttl reap ever runs, so witharchivedeclared the filter guards a code path that is never executed ... while the Archiver itself copies and hot-deletes bycreated_atage alone"Once #10347 lands, the second half of each is false: with
ttldeclared the Archiver moves rows by the ttl cutoff onttl.field, not bycreated_atage. An author who reads the message is told the sweep never runs, which is now wrong about their own object.Two separable pieces
ttlaccepts no row filter, so atransientobject with terminal rows in-band cannot spare them — givettlanonlyWhenmirroringretention.onlyWhen#10165 refused the pair on the stated grounds that the filter would guard a never-executed path. That premise is gone for plainttl. Whetherttl.onlyWhenshould now become meaningful underarchive— the Archiver would have to spread the filter into its candidate read the wayreap()does — is a real question, and it narrows/widens the acceptance face (Clause ②), so it needs its own ruling and the contract-review tier.The
retention.onlyWhenxarchiverefine beside it is unaffected: withretentionand nottlthe Archiver still moves rows bycreated_atage.