Skip to content

fix(mission): terminated grant no longer revives to Active after expiry - #8

Merged
anivar merged 2 commits into
mainfrom
fix/mission-revival-after-expiry
Aug 2, 2026
Merged

fix(mission): terminated grant no longer revives to Active after expiry#8
anivar merged 2 commits into
mainfrom
fix/mission-revival-after-expiry

Conversation

@anivar

@anivar anivar commented Aug 2, 2026

Copy link
Copy Markdown
Owner

Fixes the terminated-grant revival found in the pre-release claim audit (#7).

The bug

A terminated Mission re-registered as Active once its own expiry lapsed: the registry evicted the terminated tombstone at expiry and approve() had no expiry-in-the-future guard, so re-approving the identical grant returned 200 (Active) instead of a refusal. An already-expired mission also registered Active on first approval.

The proven kernel (decay and the eight other invariants) and the tamper-evident ledger were correct throughout — the terminate is recorded before it is reported (decern-server), so the audit trail stays honest and would in fact show the revival. The gap was purely in the registry enforcement layer above the kernel.

The fix — both halves (one without the other leaves a window)

  • decern-identityapprove() rejects expiry <= now: a dead mission cannot be granted (closes the identity path).
  • decern-store — terminated tombstones are retained for an explicit horizon past their expiry instead of being evicted in the same GC pass, so the store itself keeps refusing re-registration of a terminated s256, independent of approve().

Tests (failing-first)

  • decern-store::terminated_mission_does_not_revive_after_expiry — reproduced the revival (failed before, passes after).
  • decern-identity::approve_refuses_an_already_expired_mission + no_post_expiry_revival_of_a_terminated_mission.
  • Existing mission_registry_gc_drops_expired_on_write still passes — active-expired entries are still evicted; only terminated tombstones are retained.

clippy -D warnings + fmt clean; workspace builds.

Closes #7

anivar added 2 commits August 2, 2026 19:21
…piry

The registry evicted a terminated tombstone at its own expiry, and approve() had
no expiry-in-the-future guard, so re-approving an identical grant after it lapsed
returned Active (200) instead of a refusal — expiry laundered a termination. The
proven kernel and the tamper-evident ledger were correct throughout (the terminate
is recorded before it is reported); this was a registry-layer enforcement gap.

Fix, both halves (one without the other leaves a window):
- decern-identity: approve() rejects expiry <= now (a dead mission cannot be granted)
- decern-store: terminated tombstones are retained for a horizon past expiry, so the
  store itself keeps refusing re-registration of a terminated s256

Failing regression tests landed first (store-level revival + identity-level
expired-approve), then the fix.

Closes #7

Signed-off-by: Anivar Aravind <anivar.aravind@gmail.com>
…view nits)

Adversarial review of the revival fix returned merge-safe with three non-blocking
nits; addressing them:
- decern-store: mission_register now refuses registering an already-expired entry
  (expiry <= now), so the store is self-monotone for ALL callers, not only via
  approve(). Closes the direct-register-after-tombstone-horizon path (unreachable
  via HTTP, but the doc claimed more than the code guaranteed). + regression test.
- decern-store: soften the retention-const doc ('bounds how long a tombstone
  lingers', not 'caps map growth').
- decern-identity: rename the identity-half test to
  approve_refuses_reviving_an_expired_terminated_grant (it exercises approve()'s
  guard, not the store half it was misleadingly named after).

Signed-off-by: Anivar Aravind <anivar.aravind@gmail.com>
@anivar
anivar merged commit 859e328 into main Aug 2, 2026
2 checks passed
anivar added a commit that referenced this pull request Aug 2, 2026
…#10)

Bumps all 9 crates and both SDKs to 0.1.1. 0.1.1 is the recommended version:
it includes the Mission terminated-grant revival fix and the pre-release honesty
corrections; 0.1.0 has the revival bug.

Signed-off-by: Anivar Aravind <anivar.aravind@gmail.com>
@anivar
anivar deleted the fix/mission-revival-after-expiry branch August 4, 2026 11:23
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.

Mission: a terminated grant revives to Active after its own expiry (registry GC evicts the tombstone)

1 participant