Skip to content

Operator-reviewed cleanup apply should waive the lifecycle recency grace window for unchanged reviewed rows #888

Description

@chubes4

Follow-up to #886 / #887

#887 correctly moved retention recent-activity protection off scanner heartbeats and onto genuine lifecycle timestamps (created_at/finalized_at/cleanup_eligible_at) with a 24h grace window.

Remaining friction: the grace window applies unconditionally at apply time — including to workspace cleanup apply <run-id>, which only runs after an operator has reviewed the persisted plan. Result observed live on 2026-07-12 (post-#887, verified installed at 9eb1f11): rows auto-finalized cleanup_eligible at 01:54Z with clean upstream-equivalence evidence were planned at 20:53Z, reviewed, applied — and every row was re-protected by lifecycle recency. Any plan→apply cycle within 24h of eligibility is a guaranteed no-op, which defeats the reviewed-apply workflow the tool itself recommends as the daily path.

Fix shape

The grace window exists to keep automatic removal from racing the finalizer. An operator-reviewed apply is explicit human sign-off, so:

  • At apply time for a reviewed plan row, waive the lifecycle-recency protection iff the row's lifecycle timestamps (finalized_at, cleanup_eligible_at, created_at, lifecycle_state) at apply exactly match those captured in the reviewed plan row. Unchanged timestamps mean the operator reviewed exactly this state — the review is the safety.
  • If any lifecycle timestamp moved after plan creation (re-finalized, state change), keep the protection: the evidence is stale and the row should be re-planned.
  • All other apply-time revalidation (dirty, unpushed, containment, primary/external safety probes) remains fully intact and unconditional.
  • Non-reviewed destructive paths (bounded applies, drains, emergency cleanup) keep the grace window unchanged.

AI assistance

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions