Skip to content

feat(mandala)!: remove the unguarded 'recover' admin action kind#263

Merged
sirdeggen merged 2 commits into
mainfrom
mandala-remove-recover
Jul 1, 2026
Merged

feat(mandala)!: remove the unguarded 'recover' admin action kind#263
sirdeggen merged 2 commits into
mainfrom
mandala-remove-recover

Conversation

@sirdeggen

Copy link
Copy Markdown
Contributor

Why

The Mandala protocol had two admin actions that both looked like "recover a frozen output," but only one conserved supply:

  • reissue — fully guarded frozen-output recovery. MandalaTopicManager enforces: target outpoint must be frozen, minted amount must equal the frozen row's amount (reissueGuardFails b), zero FT inputs of the asset; the reducer then evicts the outpoint. Circulation is conserved.
  • recover — credited issuance like issue, but with no reissue guard and no reducer handler. An arbitrary issuer mint, untied to any frozen output, with no eviction. In the demo app its UI was labelled "recover a frozen output · net supply unchanged," so recovering less than the frozen value silently dropped circulating supply.

recover was redundant with reissue (legitimate seizure) and with issue (plain minting), and it was a footgun. Remove it so it can't be used by accident.

Changes

  • @bsv/templates — drop 'recover' from MandalaActionKind.
  • @bsv/overlay-topics — stop crediting 'recover' as issuance in the admit path; a stray 'recover'-labelled mint now fails the conservation check (belt-and-suspenders). Update the Gate-1 and reducer comments.
  • Tests — retitle/retarget the two cases that referenced recover: the frozen-input-spend rejection is kind-agnostic, and the forged-admin-entry case uses a still-valid kind.

Verification

  • @bsv/templates: build ✓, 46 tests pass.
  • @bsv/overlay-topics: build ✓, 277 pass / 1 skipped.

Breaking change

recover is no longer a valid MandalaActionKind. Nothing in the stack emits it — the demo app already routes recovery through reissue. Warrants a version bump at publish time (your call on major/minor, per the usual manual tag + publish).

🤖 Generated with Claude Code

'recover' credited issuance like 'issue' but had no reissue guard and no
reducer handler — an arbitrary issuer mint with no tie to a frozen output and
no eviction. Presenting it as "recover a frozen output" let an issuer mint a
different amount than the frozen value and silently change circulating supply.

Frozen-output recovery is 'reissue', which is fully guarded: target outpoint
must be frozen, minted amount must equal the frozen row's amount, zero FT
inputs of the asset, and the reducer evicts the outpoint — so circulation is
conserved. 'recover' was redundant with that (for legitimate seizure) and with
'issue' (for plain minting), so remove it entirely.

- @bsv/templates: drop 'recover' from MandalaActionKind.
- @bsv/overlay-topics: stop crediting 'recover' as issuance in the admit path
  (a stray 'recover'-labelled mint now fails the conservation check), update
  the Gate-1 comment, and adjust the reducer comment.
- Tests: retitle/retarget the two cases that referenced 'recover' (the
  frozen-input-spend rejection is kind-agnostic; the forged-admin case uses a
  still-valid kind).

BREAKING CHANGE: 'recover' is no longer a valid MandalaActionKind. Nothing in
the stack emits it; frozen-output recovery uses 'reissue'.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AbNQBGybrgwd9Af2Zmurq8
…cs 1.4.1

Roll both package versions so the 'recover' removal can be tagged and
published. overlay-topics consumes templates via workspace:^, resolved to the
new version at publish.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AbNQBGybrgwd9Af2Zmurq8
@sirdeggen sirdeggen merged commit ee21cf6 into main Jul 1, 2026
7 checks passed
@sonarqubecloud

sonarqubecloud Bot commented Jul 1, 2026

Copy link
Copy Markdown

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