Skip to content

Archive/unarchive for pending proposals (reversible retraction) — phase 2 of #337 #351

Description

@haseebrabbani

Background

#337 was split in two after the discussion there:

  • Phase 1 (PR fix: count only viable proposals toward the pending-proposal cap #350): stale proposals — those built on a superseded prev_commitment — no longer count toward GUARDIAN_MAX_PENDING_PROPOSALS_PER_ACCOUNT, fixing the permanent PendingProposalsLimit lockout.
  • Phase 2 (this issue): a way for a proposer to deliberately retract a live, still-viable proposal — e.g. withdrawing it before cosigners sign — via a reversible archive/unarchive mechanism rather than hard deletion.

Design sketch below is from @zeljkoX's comment on #337.

Proposed design

  • Replace deletion with reversible archive/unarchive.
  • Store archived_at separately from DeltaStatus — archival is proposal metadata, not a delta lifecycle state.
  • Only the original proposer may archive or unarchive.
  • Archived proposals cannot be signed or submitted and do not consume the pending-proposal limit.
  • Unarchive succeeds only if the proposal remains viable (derived from current account state — primarily prev_commitment plus network validation), no candidate exists, and capacity is available.
  • Archive / sign / unarchive / candidate creation must use atomic conditional storage operations to prevent races.
  • Support both Postgres and the default filesystem backend, plus HTTP and gRPC, so the Rust and TS clients stay aligned.
  • Hard deletion is optional retention work on top of this — e.g. purge archived payloads after 30 days while retaining a minimal audit tombstone.

Open questions

  • Proposer identity/authz: nothing today ties a proposal to an authenticated proposer identity (DeltaStatus::Pending carries a proposer_id, but it isn't verified against the caller's credentials). "Only the original proposer may archive" needs an authz story before implementation.
  • Whether archived proposals should appear in pull_pending_proposals (flagged) or only via a dedicated listing.
  • Client API shape (multisig.archiveProposal(commitment) / unarchiveProposal(commitment)?) and how it relates to the abandon flow from abandon candidate endpoint #327.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    Status
    Backlog

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions