Repository navigation
purge --check-policy: add a retention horizon for checkpoint-* directories #1069
Description
CR-A10-042 (from #102) noted the retention scan (forgelm/cli/subcommands/_purge.py _check_policy horizons list, ~:1210-1232) covers audit_log, staging dirs, compliance bundle, data-audit report and raw_documents, but not checkpoint-* directories, which every completed run leaves under training.output_dir. The memorisation-warning side of CR-A10-042 is being fixed on branch issue-102-purge-config-memorisation; the retention horizon needs its own config field (e.g. retention.checkpoint_retention_days, default 0 = disabled, opt-in per project principle 8) plus a _discover_checkpoint_horizons helper mirroring _discover_per_run_staging_horizons, tests, and EN+TR doc updates to docs/reference/purge_subcommand.md and the audit/retention reference pages. Refs #102, CR-A10-042.
Acceptance criteria
-
retention.checkpoint_retention_days(int,ge=0, default0= never reported) with a description that names the report, not enforcement. The default stays0: the other three horizons default to non-zero values, but a non-zero default here would add violations to every existing install that still has old checkpoints and flip thecount == 0gate of thejq -erecipe indocs/reference/purge_subcommand.md. -
forgelm purge --check-policyreports eachcheckpoint-*directory directly under--output-dirolder than the horizon, ascheckpoint_dir[<name>], withage_source=mtime. These directories are not run-scoped, so they must not take the audit log's genesis age (_resolve_artefact_agefalls back to it for any artefact without arun_id). - A fresh checkpoint inside the horizon, a non-directory entry named
checkpoint-*, and a horizon of0are not reported; tests pin the exact boundary. - The scan root is
--output-dir, like every other horizon; following config-named training or pipeline layouts is out of scope here. -
config_template.yaml, the field-description guard, the wizard-defaults sync guard and the EN+TR docs are updated per theadd-config-fieldskill (docs/reference/purge_subcommand.md,docs/reference/configuration.md, the GDPR erasure guide and manual page). The docs say plainly that checkpoints are reported, never deleted. - Size budget:
forgelm/config.pyhas no headroom andforgelm/cli/subcommands/_purge.pyvery little, so record abudget_historyentry intools/check_module_size.py(decision C-18) or place the helper in a new module.
Metadata
Metadata
Assignees
Labels
Type
Projects
- StatusShow more project fieldsTodo
Activity
fix(purge): warn about the weights a run really leaves behind (#102)
cemililik commentedon Oct 23, 2026
Triaged on
developmente6bf28d, after #1068 merged during this triage. Each finding was first checked on 83e62f6 and on #1068's head (ab5ce5f), whose code is identical to the merge.Accepted: enhancement, severity low, wave 4, under the W4 module-sweep epic #875.
What I checked
_scan_retention_violationshas nocheckpoint-*horizon ondevelopment. purge: find the weights a run really leaves behind (fixes #102) #1068 keeps it that way on purpose (its docstring: "checkpoint-*directories are deliberately not walked: noretention:horizon covers them") and documents the limit. This issue is the opt-in way to close it. It stays low because purge: find the weights a run really leaves behind (fixes #102) #1068 already makes the memorisation warning list these directories; what is missing is only the Art. 5(1)(e) report.training.save_total_limit(default 3)checkpoint-*directories once it passestraining.save_steps(default 200) steps, and nothing removes them afterwards, auto-revert included.Two points I added to the acceptance criteria (the body now has a list; it had none)
0is right, and not only because of principle 8. The other three horizons default to non-zero values, but a non-zero default here would add violations to every existing install that still has old checkpoints, and flip thecount == 0gate of thejq -erecipe indocs/reference/purge_subcommand.md._resolve_artefact_agefalls back to the log's genesis timestamp for any artefact without arun_id. A checkpoint is not run-scoped by name, so one written yesterday into a long-lived output directory would be reported at the log's age (the same false-positive family as CR-A10-023 in [Wave 3] Medium — Module sweep: GDPR purge / reverse-pii and the human-approval gate (part 1/2) #554).Notes for whoever implements it
--output-dir, like every other horizon. A retention-only--config(forgelm purge --check-policy --config requires a complete ForgeConfig; a file with only a retention block exits 1 #1054) has notrainingblock, so the config cannot name the directory.forgelm/config.pyandforgelm/cli/subcommands/_purge.pyboth have 0 LOC of headroom ondevelopment(purge: find the weights a run really leaves behind (fixes #102) #1068 raised the_purge.pybudget by 80, to 1304, and used it). Either add abudget_historyentry intools/check_module_size.py(decision C-18) or put the helper in a new module. Splitforgelm/cli/subcommands/_purge.pyinto a sub-package (_row_id,_run_id,_check_policy,_shared) — deferred until Phase 16 S9 has landed #908, the_purge.pysplit, is deferred until Phase 16 S9._artefact_targets_for_run, not the retention report. It does edit the same module._is_artefact_name,_final_model_names).Not open for contribution yet: this needs a maintainer decision first. If you would like to work on it, please comment with your proposed approach before opening a pull request.