Skip to content

bug: keep terminal run bundles protected until their live lease is released #354

Description

@codeforester

Problem

Another invocation can delete a still-active run bundle while its consumer cleanup hook is running. Terminal metadata is written before cleanup; retention consults the live lease only when metadata status is running. The documented lifetime protection therefore ends too early.

Verified evidence

Reviewed on 2026-09-17 at 2d67cd24e8d704386f2be7d3a41addc06fb81e17 (local checkout matched GitHub main). Reproduced in isolated macOS environments with Python 3.14.6. Framework default probe environment: Click 8.5.0 and Typer 0.27.2. Demo probes used released base-cli 0.4.3 unless noted.

A public-API two-process probe used the same application/cache namespace and RetentionPolicy(max_bundles=1). The first command wrote a temporary marker and registered an on_cleanup hook. That hook confirmed the marker existed, launched a second ordinary invocation, then checked it again:

first invocation exit: 0
metadata status during cleanup: ok
marker before second invocation: present
second invocation exit: 0
marker after second invocation: absent
first run root after second invocation: absent

The first process still held its lease. _finish_run_recorder() precedes context.cleanup(), and both retention discovery and destructive revalidation skip the lease check for ok/error/aborted records. No malicious filesystem mutation is required.

Sources:

Acceptance criteria

  • Protect a held live lease regardless of whether run.json is running or terminal; retain unknown liveness safely under the documented policy.
  • Revalidate liveness before deletion and preserve protection through cleanup hooks, telemetry teardown, and logger/resource close.
  • Add a deterministic two-process regression with terminal metadata and a blocked cleanup hook; cover native and attached lifecycles.
  • After the owner releases its lease, prove normal count/age/byte retention still removes eligible finished bundles.

Related work

Follow-up to closed #266 and #62. Distinct from open #341: this loses files across processes, rather than handlers in nested same-process runs.

Project fields

  • Status: Backlog
  • Priority: P1
  • Area: Runtime
  • Initiative: v1.0 Readiness
  • Size: M
  • Assignee: @codeforester
  • Milestone: v1.0.0
  • Target date: unscheduled

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

bugSomething is not working

Type

Projects

  • Status
    In Progress

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions