Skip to content

fix(delete): apply must rebuild the retirement evidence the approver signed - #125

Merged
rldyourmnd merged 1 commit into
mainfrom
fix/delete-apply-preserves-approved-retirement
Sep 10, 2026
Merged

fix(delete): apply must rebuild the retirement evidence the approver signed#125
rldyourmnd merged 1 commit into
mainfrom
fix/delete-apply-preserves-approved-retirement

Conversation

@rldyourmnd

@rldyourmnd rldyourmnd commented Sep 10, 2026

Copy link
Copy Markdown
Contributor

gds repository delete --apply could not succeed for any repository.

The precondition observer is constructed twice — once when the plan is stored, once when it is applied — and the two sites had drifted. The apply site set neither retirement nor preserve. Without the retirement reader every remote collection stays unread, and gatherRetirementEvidence classifies unread as unknown, which blocks by design. Without the preserved set every identity the operator explicitly accepted losing reads as blocking again. Retirable was therefore false on every apply, the observation returned an error, and the engine reported it as GDS_STALE_PLAN — "observed repository state no longer matches the plan" — with an empty mismatch list in the journal. The state had not changed; the observation had failed. Nothing in the tree tested this path.

Passing --preserve again at apply could not have fixed it either: the declaration belongs to the plan the approver signed, and it was not stored anywhere.

  • ProviderTransition.PreservedIdentities now carries the accepted losses, so they live in the plan parameters and inside the plan digest the approval binds. StepTransition rejects a non-string entry rather than silently dropping it.
  • newRepositoryDeleteObserver becomes the single construction site for both paths, so they cannot drift again. Both preserve and retirement derive from the stored transition.
  • --preserve joins --inventory-root and --confirm-* as a planning input refused on apply, which is what it always was in substance.

Tests: the parameter round trip now covers the preserved set and its rejection of a non-string entry, and a new core/app test asserts the shared observer carries the approved declaration and analysis root.

Because the Go sources are part of this repository's own compiled policy inputs, .gds/bundle.lock.yaml and .github/workflows/gds-ci.yml are regenerated through gds generate repository --plan/--apply with a binary built from this branch; without that, GDS_CONTEXT_POLICY_SOURCE_DIGEST_MISMATCH fails core/assurance, core/cli and core/context.

Verification: scripts/validate_go_core.sh --quick exits 0 — 66 packages ok, no failures.

https://claude.ai/code/session_01CKXKXND4zAgWisTtatyTHX

…signed

`gds repository delete --apply` could not succeed for any repository. The
precondition observer is built twice — once when the plan is stored, once when
it is applied — and the apply site set neither `retirement` nor `preserve`.
Unread remote collections classify as unknown, which blocks; an empty preserved
set turns every accepted loss back into a blocker. `Retirable` was false on
every apply, and the failed observation surfaced as GDS_STALE_PLAN with an
empty mismatch list.

The accepted losses now travel on the transition, so they are inside the plan
parameters and the plan digest the approval signs, and one constructor serves
both paths so they cannot drift again.

Claude-Session: https://claude.ai/code/session_01CKXKXND4zAgWisTtatyTHX
@rldyourmnd
rldyourmnd force-pushed the fix/delete-apply-preserves-approved-retirement branch from d4ee5f5 to 23c330e Compare September 10, 2026 18:52
@rldyourmnd
rldyourmnd merged commit 18a449b into main Sep 10, 2026
8 of 9 checks passed
@rldyourmnd
rldyourmnd deleted the fix/delete-apply-preserves-approved-retirement branch September 10, 2026 19:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant