From 646a33f2f536051d4ab51f5be706e9cc45264436 Mon Sep 17 00:00:00 2001 From: donkey-ai Date: Sun, 28 Jun 2026 23:02:25 -0400 Subject: [PATCH] feat(v0.4.7): report area 500px, heirs one-per-line, wizard line breaks, ALL-DUST guard Owner-approved changes after testing v0.4.6, plus accumulated v0.4.x work, task-tracking notes, and an updated project HANDOFF document. The four v0.4.7 changes: 1. Report area (BalBuildWillDialog) opens 500px tall (min) up to 700px (max), then the scrollbar takes over. Previously it opened ~140px (too short). 2. Heirs are listed ONE per line again (green, bold) in _build_success_report, reverting the v0.4.6 single-line form. Heir names can be long and the report now scrolls, so compression is no longer needed. 3. Two wizard texts get an explicit line break: after "(or backup)" in the date hint and after "miner fees" in the fee note (widgets.py). 4. ALL-DUST guard: when EVERY heir's share is below the Bitcoin dust limit, the inheritance would pay nobody. Heirs.prepare_lists now raises HeirAmountIsDustException at the end (where all heirs across all locktimes are known with their final dust state), and dialogs.task_phase1 shows a clear RED message and stops without building/signing/checking. A mix of dust + valid heirs keeps building normally. The guard is intentionally in prepare_lists, NOT prepare_transactions (which only sees the lowest locktime and would false-positive). HeirAmountIsDustException is imported in common.py. Tests: 3 new tests in test_core_heirs_extra.py pin the dust behaviour (all-dust raises; mixed continues; multi-locktime continues). Full suite: 258 passed. ruff: no new errors. Version bumped 0.4.6 -> 0.4.7 (4 files). CHANGELOG #23. Also adds/updates HANDOFF.md so any future AI (Claude or another model) can resume the project with full context (rules, layout, build/test/lint, dust logic, git flow), and records the task-tracking notes in .agent_memory_tasks.md. --- .agent_memory_tasks.md | 829 ++++++++++++++++++++++ CHANGELOG.md | 571 +++++++++++++++ HANDOFF.md | 377 +++++----- bal/VERSION | 2 +- bal/__init__.py | 2 +- bal/core/heirs.py | 37 + bal/core/plugin_base.py | 34 +- bal/core/will.py | 70 +- bal/core/willexecutors.py | 15 +- bal/gui/qt/common.py | 3 +- bal/gui/qt/dialogs.py | 451 ++++++++++-- bal/gui/qt/lists.py | 6 +- bal/gui/qt/plugin.py | 99 ++- bal/gui/qt/widgets.py | 298 ++++++-- bal/gui/qt/window.py | 43 +- bal/manifest.json | 2 +- tests/test_core_heirs_extra.py | 92 +++ tests/test_group_f_heir_change_rebuild.py | 116 +++ tests/test_group_g_basic_calendar.py | 79 +++ 19 files changed, 2803 insertions(+), 323 deletions(-) create mode 100644 .agent_memory_tasks.md create mode 100644 tests/test_group_f_heir_change_rebuild.py create mode 100644 tests/test_group_g_basic_calendar.py diff --git a/.agent_memory_tasks.md b/.agent_memory_tasks.md new file mode 100644 index 0000000..591ded5 --- /dev/null +++ b/.agent_memory_tasks.md @@ -0,0 +1,829 @@ + +## TASK A (proposto, NON ancora avviato) — Migliorare il messaggio "WILL EXPIRED" + +**Origine:** osservato dall'utente negli screenshot del 23/06/2026 (will scaduto -> percorso invalidate + re-sign). La LOGICA è corretta; si migliora solo la UX/chiarezza del messaggio. + +**3 miglioramenti approvati dall'utente (da implementare poi, in inglese, regole R1-R4 + zip-first):** +1. Tradurre il timestamp Unix grezzo (es. 1782118800) in data leggibile. + Esempio: invece di "Will Expired 9f1b0a75...: 1782118800" + mostrare "Will expired (locktime 2026-06-22 11:00 UTC) - too late to anticipate, will invalidate and re-sign". +2. Rendere il messaggio INFORMATIVO e non un ERRORE: il rosso sembra un errore, + ma e' un flusso normale. Usare colore di avviso (arancione) o aggiungere frase + tipo "This is expected: the will is past its locktime, switching to invalidate + re-sign." +3. Accorciare l'hash del will per leggibilita' (es. primi 8 + ultimi 4 caratteri). + +**Note tecniche da fare in DISCOVER quando si avvia:** +- Trovare il punto del codice che genera la stringa "Will Expired ... " (probabilmente nel wizard "Building Will"). +- Verificare se il colore rosso e' impostato li' (rich text / stylesheet). +- Seguire METHOD: DISCOVER -> PLAN (attendere OK) -> EXECUTE -> VERIFY -> ZIP-first -> commit/PR/release solo dopo conferma. + +## TASK B (proposto, NON ancora avviato) — Etichette descrizione transazioni in Cronologia + +**Origine:** osservato dall'utente nello screenshot Cronologia del 23/06/2026. +Nella tab "Cronologia" di Electrum (transazioni on-chain), il plugin BAL scrive +una descrizione colorata nella colonna "Descrizione". + +**Stato attuale:** +- La transazione di EREDITA' e' etichettata "BAL Transaction" (colore rosso). +- La transazione di INVALIDATE NON ha alcuna descrizione. + +**Modifiche richieste (approvate dall'utente):** +1. RINOMINARE l'etichetta dell'eredita': "BAL Transaction" -> "BAL Inheritance transaction". +2. CAMBIARE il colore dell'etichetta eredita' da ROSSO a VERDE. +3. AGGIUNGERE una nuova etichetta per le transazioni di invalidate: + "BAL Invalidate transaction" in colore ARANCIONE (oggi compaiono senza descrizione). + +**Riepilogo finale desiderato:** +| Transazione | Etichetta desiderata | Colore | +|-------------|-----------------------------|-----------| +| Eredita' | BAL Inheritance transaction | VERDE | +| Invalidate | BAL Invalidate transaction | ARANCIONE | + +**Note tecniche da fare in DISCOVER quando si avvia:** +- Trovare nel codice dove viene impostata l'etichetta "BAL Transaction" + (probabilmente wallet.set_label(txid, ...) o simile) e dove/come e' impostato il colore. +- Capire come il plugin distingue una tx di eredita' da una di invalidate, per + applicare l'etichetta corretta a ciascuna. La tx di invalidate oggi NON riceve + label -> trovare il punto dove viene creata/broadcastata e aggiungere lì set_label. +- Verificare se il colore (rosso) e' gestito da Electrum o dal plugin, e come + impostare il verde per l'eredita'. +- Seguire METHOD: DISCOVER -> PLAN (attendere OK) -> EXECUTE -> VERIFY -> ZIP-first -> commit/PR/release solo dopo conferma. + +## TASK C (proposto, NON ancora avviato) — Checkbox "no will-executor" anche in Plugin Settings + +**Origine:** richiesta utore del 23/06/2026. +Nel wizard "Create your WILL", finestra di download will-executor, esiste il checkbox +"Add transactions without willexecutor". L'utente vuole lo STESSO checkbox anche nella +finestra "Plugin settings" (stesso stile delle altre righe), default ON, con un +HelpButton che spiega la funzione. + +**Testo del tastino di aiuto (fornito dall'utente, da usare verbatim):** +"Create a will that does not require a Will-executor; it can be saved, for example, +on a USB stick, and a copy can be given to the heirs." + +**SCOPERTA IMPORTANTE (DISCOVER gia' fatto):** +- La config ESISTE GIA': `self.NO_WILLEXECUTOR = BalConfig(config, "bal_no_willexecutor", True)` + in `bal/core/plugin_base.py:193` (default True = ON). Quindi NON va creata. +- Il checkbox del wizard e' in `bal/gui/qt/lists.py:916-918`: + hbox.addWidget(QLabel(_("Add transactions without willexecutor"))) + heir_no_willexecutor = BalCheckBox(self.bal_plugin.NO_WILLEXECUTOR) + -> usa BalCheckBox legato alla stessa config. Aggiungendo lo stesso checkbox nelle + settings, i due rimangono sincronizzati automaticamente (stessa BalConfig). +- La finestra Settings e' `settings_dialog()` in `bal/gui/qt/plugin.py:372`. + Usa una griglia con la helper `add_widget(grid, label, widget, row, help_)` + (definita in `bal/gui/qt/common.py:98`) che mette: QLabel(col0), widget(col1), + HelpButton(col2). Le righe attuali vanno 1..8 (8 = bottone Rebroadcast). +- Esiste gia' codice COMMENTATO che faceva esattamente questo (plugin.py:382 e + 536-542): `# heir_no_willexecutor = BalCheckBox(self.NO_WILLEXECUTOR)` e un + add_widget "Backup Transaction" -> si puo' riattivare/adattare. +- C'e' anche un blocco "Reset setting" (on_reset_defaults, plugin.py:560-596) con + una lista `resets = [...]`: per coerenza la nuova checkbox va AGGIUNTA a quella + lista cosi' il Reset la riporta al default (ON). + +**PLAN bozza (da rifinire e far approvare quando si avvia):** +1. In `settings_dialog()`: creare `heir_no_willexecutor = BalCheckBox(self.NO_WILLEXECUTOR)`. +2. Aggiungere una riga con `add_widget(grid, "