Skip to content

release: 0.7.3, the toolbox 0.7.4 (#66): no retire of a transaction a broadcaster took; the doors' word for a refused post; the spend guard; the vector; the yanked crates moved - #15

Merged
Calgooon merged 4 commits into
mainfrom
align/toolbox-0.7.4
Oct 10, 2026
Merged

Calgooon merged 4 commits into
mainfrom
align/toolbox-0.7.4

Conversation

@Calgooon

Copy link
Copy Markdown
Contributor

bsv-stack-lean #66 and the tracker's rule reaching the CLI (docs/p0/align-cli-073.md): the toolbox 0.7.4 (no count and no broadcaster word writes failed or invalid); every retire path of the CLI (the served sweep, the by-hand pass, cleanup_abandoned and the daemon, the served follow-up, /abortAction) writes failed only for a transaction no broadcaster ever took, the charter's built, and never for one a broadcaster accepted (#24); the BROADCAST_REJECTED arm is gone and a refused /createAction, /signAction or /internalizeAction answers with the word built, the request, its hint and inputs locked, promising no release; the spend guard holds the coins of a transaction that drew an immediate refusal until a status source holds it; the toolbox 0.7.4's arcade_status_verdicts.json carried byte-identical (cmp); fastrand and spin moved off their yanked versions. Twelve witnesses, eight red on 0.7.2 and the handler's red on the 0.7.3 toolbox; 356 tests, fmt, clippy, both release builds, the vector jobs and the dry run green on the lane's host and verified by the captain. The report structs and the doors' response types gain a field each, named in the CHANGELOG.

🤖 Generated with Claude Code

Calgooon and others added 4 commits October 10, 2026 00:50
…h yanked in the lock since 0.7.1)

cargo update -p bsv-wallet-toolbox-rs; cargo update -p fastrand -p spin:
three packages moved, nothing else. RUSTFLAGS=-Dwarnings cargo build
--workspace --all-targets --locked: exit 0, no source line changed.

The suite at this commit: 337 passed, 2 failed, both by the toolbox 0.7.4's
first half (#66: an Arcade push REJECTED or DOUBLE_SPEND_ATTEMPTED is a hint
that writes no word):
- arcade_webhook_vector_tests: the CLI's vector still carries 0.7.3's four
  toolbox_push values (invalid, double_spend); the next commit copies the
  toolbox 0.7.4's file.
- arc_callback_tests::rejected_status_marks_double_spend asserted the old
  word (req doubleSpend, tx failed); rewritten to the rule after.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…fusal is a hint (#66)

The vector is the toolbox 0.7.4's file, copied and proven byte-identical
with cmp against the crate's file in the cargo registry (sha256
80d2ac72...f954). It moves four toolbox_push values to none
(push_rejected_467, push_rejected_466_conflict, push_double_spend_attempted,
push_rejected_lower_case) and that outcome's description; nothing else.
arcade_webhook_vector_tests: 4 passed on it. The test's arms that read
invalid and doubleSpend stay: no case expects them now, and a storage that
wrote either would show as a mismatch.

arc_callback_tests: rejected_status_marks_double_spend asserted req
doubleSpend and tx failed on a pushed DOUBLE_SPEND_ATTEMPTED; renamed
a_pushed_double_spend_word_is_a_hint_that_writes_no_word and asserts the
rule: unmined/unproven kept, broadcasterRefusalHint on the request's history.
src/arc_ingest.rs: the module doc no longer calls a 466 a conflict.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…transaction a broadcaster took; the doors' word for a refused post; the spend guard

The retire paths (src/retire_guard.rs). The tracker allows the host's
retire on `built` alone (bsv-stack-lean docs/charters/tracker.md sections 1
and 5; #24, never abort a template already broadcast). `broadcaster_took`
reads the wallet's own records for an accepting word: the proof request past
the post (`unmined`, `callback`, `unconfirmed`, `completed`), an
`accepted`/`seen`/`mined` broadcast-memory row, the tracker's stored word
past `built`. The memory alone is not enough: its ladder overwrites a
provider's `accepted` with a later `rejected`.
- broadcast_reconcile: a chain-index absence of a transaction the
  broadcaster holds is named and never a root (rule 5); the rejected-row,
  fatal and sweep roots retire through `retire_never_announced`, which
  learns the set from a dry run (climb, root, descendants) and refuses it
  whole when a broadcaster took any member (`kept_announced` in both
  reports). The served sweep at 0.7.2 retired every unproven transaction
  with a `rejected` row, which the toolbox 0.7.4 writes as a hint.
- cleanup_abandoned (the daemon's 300 s ticker and the command): the
  absence past the threshold is `AbsentPastThreshold`, kept (was
  `DeadAbsentPastThreshold`, abandoned); a definitive absence abandons only
  a transaction no broadcaster took (`absent_announced` otherwise); a
  confirmed competitor's spend (`DeadConflict`) is unchanged; the
  descendants' retire goes through the same guard.
- the served follow-up retires on a `Rejected` probe only a transaction no
  broadcaster took; `/createAction` answers 502 only when it did retire.
- `/abortAction` refuses (409) a transaction a broadcaster took; the
  toolbox's 0.3.60 broadcast abort honours one with no chain evidence.

The doors' word (src/server/post_word.rs). At the toolbox 0.7.4 no
broadcaster word reaches "Transaction broadcast failed": the classify arm
and its sentence "the tx is already failed and its inputs released" go.
`/createAction` and `/signAction` with `sending`, and `/internalizeAction`,
answer `broadcast: {word: "built", request, hint, inputs: "locked"}` from
the request's status and its last `immediateBroadcastHint`; nothing is
promised released. The 502 `BROADCAST_REJECTED` message of the inline
retire promises a release only where the chain vouches the coin unspent.
The MCP tools say the same.

The spend guard (src/spend_guard.rs; the charter section 4, Reask.spend).
A coin of a transaction whose request is still `unsent`/`sending` with an
`immediateBroadcastHint` (no status source holds it) is held: not spendable,
recorded in `spend_guard_holds`; released once the request is `unmined` or
`completed`; dropped without restoring when the transaction is retired. It
runs before every spend (`/createAction` under the spending lock, `send`,
`drain`, `split`, `gift-send`) and on each served pass.

Witnesses (src/tracker_words_witnesses.rs), 12. RED on 0.7.2's source at
the toolbox 0.7.4 (8a902b3, the guard absent): 8 failed, 3 passed (the
three "no broadcaster took it" retires, green both sides): the announced
transaction abandoned past the threshold and absent everywhere (daemon),
retired on a later refusal row (sweep), retired as a phantom (by hand),
retired by the follow-up, aborted 200 at the door; the refused coin
selected; not held. RED on the toolbox 0.7.3 (0.7.2's manifest and lock):
the refused createAction errs "Transaction broadcast failed ... 465". GREEN
here: 12 passed. Six older tests asserted 0.7.2's retire of a transaction a
broadcaster took and are rewritten to the rule; README, the CLI help and
the module docs no longer say an absence retires.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… broadcaster took, the doors' word for a refused post, the spend guard, the vector, the yanked crates moved

CHANGELOG 0.7.3: the toolbox 0.7.4 and #66; fastrand 2.5.0 and spin 0.9.9
(yanked 2.4.0 and 0.9.8 left the lock); the vector byte-identical to the
toolbox 0.7.4's, its four toolbox_push values; the retire paths against the
tracker's words; the doors' word (`broadcast`, `built`) where 502
BROADCAST_REJECTED promised released inputs; the spend guard; the upgrade
(the table `spend_guard_holds`, the doors' new answer, the report structs'
new fields) and the rollback.

The gate's checks at this commit, on this host (aarch64-apple-darwin):
fmt, clippy -D warnings, both release builds, the workspace suite (356
passed, 0 failed, 0 ignored), the vector jobs (4 passed; 5 passed, the grep
ok), cargo publish --dry-run --locked.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Calgooon
Calgooon merged commit 636c6dd into main Oct 10, 2026
6 checks passed
@Calgooon
Calgooon deleted the align/toolbox-0.7.4 branch October 10, 2026 05:40
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