exlab_wizard.orchestrator.cleanup#

Staging-side cleanup helpers. Backend Spec §13.7.

Once a run is verified on the NAS, the orchestrator deletes the local staging copy. Two policies are supported:

  • manual (default for v1) – only an explicit operator action advances sync_verified -> cleared. The watcher never auto-clears.

  • scheduled – runs whose sync_verified_at was at least retain_hours ago are auto-cleared by the periodic sweep.

Deletion is logged with file count and bytes freed (§13.7).

Both helpers are pure read-side utilities except clear_run(), which performs the on-disk delete and writes the cleared history entry. The watcher keeps the responsibility of deciding when to call clear_run() – this module only enforces the policy and the filesystem effect.

Functions

cleanup_eligible(*, ingest, config[, now_utc])

Return True if the run's local staging copy should be cleared now.

clear_run(run_path, *, config, ingest_writer)

Remove the staged run directory and append the cleared entry.

freed_bytes_and_count(run_path)

Sum file count and byte total under run_path.

exlab_wizard.orchestrator.cleanup.cleanup_eligible(*, ingest, config, now_utc=None)[source]#

Return True if the run’s local staging copy should be cleared now.

Backend Spec §13.7:

  • manual – always returns False. The operator must invoke clear_run() directly (UI button or API).

  • scheduled – returns True iff current_state == sync_verified AND sync_verified_at + retain_hours <= now_utc.

A run that is not sync_verified is never eligible – attempting to clear earlier states is a contract violation that the watcher must avoid.

Parameters:
Return type:

bool

async exlab_wizard.orchestrator.cleanup.clear_run(run_path, *, config, ingest_writer, host=None)[source]#

Remove the staged run directory and append the cleared entry.

Returns (file_count, bytes_freed) so the caller can log/notify accurately. The ingest entry is written before the deletion so a crash mid-clear leaves a coherent state record.

The function is idempotent: calling it after the directory is gone is a no-op that returns (0, 0) and does not append a duplicate history entry.

Parameters:
Return type:

tuple[int, int]

exlab_wizard.orchestrator.cleanup.freed_bytes_and_count(run_path)[source]#

Sum file count and byte total under run_path.

Counts files only (directories are not counted as files); the .exlab-wizard/ cache subtree is included because clear_run() deletes the whole run.

Parameters:

run_path (Path)

Return type:

tuple[int, int]