Severity: Medium (the guard protecting the registry is conditional)
Problem
The checkpoint-removed semantic guard — which detects a commit that removes a checkpoint from the registry — only works under two conditions (detect, SemanticKind::CheckpointRemoved):
base_checkpoint_names is Some(...) — if the caller cannot/does not supply the base registry (no base ref, shallow clone, first commit), it returns vec![] and the guard is silently off.
- A changed file path ends with
checkpoints.yaml — removal achieved by other means (changing which registry file is included, or editing the global baseline outside the repo) is not detected.
Why it matters
This is the gate that protects the gate. A silent no-op when the base is unavailable means an author (or an automated flow without a base ref) can strip checkpoints undetected — the highest-leverage bypass, since removing a checkpoint disables all its future firing.
Proposed fix
When the base registry cannot be resolved, fail loud (surface a warning / distinct exit signal) rather than silently disabling the guard; broaden detection to any registry mutation path, not just files literally ending in checkpoints.yaml.
Acceptance criteria
- Inability to resolve the base registry is surfaced, not silently treated as "nothing removed".
- Removing a checkpoint is detected across the supported registry-inclusion mechanisms.
Severity: Medium (the guard protecting the registry is conditional)
Problem
The
checkpoint-removedsemantic guard — which detects a commit that removes a checkpoint from the registry — only works under two conditions (detect,SemanticKind::CheckpointRemoved):base_checkpoint_namesisSome(...)— if the caller cannot/does not supply the base registry (no base ref, shallow clone, first commit), it returnsvec![]and the guard is silently off.checkpoints.yaml— removal achieved by other means (changing which registry file is included, or editing the global baseline outside the repo) is not detected.Why it matters
This is the gate that protects the gate. A silent no-op when the base is unavailable means an author (or an automated flow without a base ref) can strip checkpoints undetected — the highest-leverage bypass, since removing a checkpoint disables all its future firing.
Proposed fix
When the base registry cannot be resolved, fail loud (surface a warning / distinct exit signal) rather than silently disabling the guard; broaden detection to any registry mutation path, not just files literally ending in
checkpoints.yaml.Acceptance criteria