Repository navigation
feat: token recovery tool + AI audit prompts + speccheck (rebased onto main) - #354
Conversation
|
Rebased onto main by felixfelix-bot (supersedes #340). Ready for c03rad0r review + merge. Token recovery tool + AI audit prompts + speccheck. All conflicts resolved during rebase. |
Amperstrand
left a comment
There was a problem hiding this comment.
Fidelity-verified against our original #340's final state — all three review-fix rounds present (grep-confirmed in the tree): unspent-only recovery ( with the PENDING retry-later status), 30s per-mint checkstate timeout, no in output, single lazily-loaded wallet. File set is exactly the reviewed 9 (tool + ai-audit + speccheck + gitignore guard), binary absent. CI green.
One note before merge: CHANGELOG entry missing — the tool is user-visible operator tooling. Suggested under Added: 'Token recovery tool + AI audit prompts + speccheck (#354)' with the unspent-only/timeout semantics mentioned. Our original rebuild (orphaned branch 92ad9b9) carried a ready entry if you want to lift the wording.
Amperstrand
left a comment
There was a problem hiding this comment.
Fidelity-verified against our original #340's final state - all three review-fix rounds present (grep-confirmed in the tree): unspent-only recovery (State != nut07.Unspent with the PENDING retry-later status), 30s per-mint checkstate timeout, no Secret[:16] in output, single lazily-loaded wallet. File set is exactly the reviewed 9 (tool + ai-audit + speccheck + gitignore guard), binary absent. CI green.
One note before merge: CHANGELOG entry missing - the tool is user-visible operator tooling. Suggested under Added: "Token recovery tool + AI audit prompts + speccheck (#354)" with the unspent-only/timeout semantics mentioned. Our original rebuild (orphaned branch 92ad9b9) carried a ready entry if you want to lift the wording.
Amperstrand
left a comment
There was a problem hiding this comment.
Reviewed. Verified locally on this head: go build clean, and a -dry-run smoke against a sample file (comment lines skipped, malformed tokens flagged, per-line + summary report, exit 0) — the documented interface works as described.
Two notes:
- Your
make/speccheck.shpasses vacuously —--comment-start "//"(no trailing space) matches zero quotes, so the check verifies nothing. #357 documents this exact trap and ships the corrected script. Recommend: merge #357 and let its version of the script land on top of yours, or drop the script from this PR. - Heads-up: the pre-cleanup branches of #360–#363 carried a compiled binary of this tool (
scripts/token-recovery/token-recovery). Your source form here is the right one — the binary copies have been dropped from those branches during the incident cleanup.
Approving — merge at your discretion (after the #357 ordering question is settled).
(E2E cloud-lab run for this head is in flight; results will follow.)
|
E2E results + changelog addition: deployed head
The token recovery tool itself was smoke-verified locally on this head: builds clean, |
Update example from old 'TollGate-ABCD-2.4GHz-1' (band suffix) to simplified 'TollGate-A1B2' (random chars only).
Token Recovery Tool: Standalone Go tool that recovers Cashu tokens from tokens-to-recover.txt (written when autopay fails with NDS gate errors). Checks proof state at mint via NUT-07 checkstate, recovers unspent tokens via Wallet.Receive(). Supports --dry-run. Also includes: - docs/ai-audit/ — 3 AI audit prompt templates (NUT compliance, security, deps) - make/speccheck.sh — one-command greatspectations spec checking Tested against testnut.cashu.exchange with real tokens.
Under set -e, a non-zero exit from 'spectate check' (drift found) aborted the script before the coverage report and propagated as the script's exit status. Drift is this script's report, not its failure mode — report and exit 0; infra errors (install/clone) still abort. CI gating can invert this deliberately when wired in. Review findings: cold-code review 2026-08-17 item 3.
…leak - PENDING proofs were treated as recoverable (state != Spent), so the tool could receive in-flight proofs — double-spend attempt or failed receive. Recoverable now requires State == Unspent for every proof; PENDING gets its own status and a retry-later message. - Wallet loads once per run (lazy, first recoverable token) instead of per line — LoadWallet locks the bolt store, per-token loads contend. - hash_to_curve error no longer prints p.Secret[:16] — proof secrets spend tokens; the slice would also panic on short secrets. - Dry-run counts recoverable tokens separately instead of as ❌ failed. - No timeout change needed: gonuts client already uses a 30s http.Client timeout (wallet/client/client.go:34). Review findings: cold review 2026-08-18 (majors 1-2 + minors 1,2,3*4).
…o a hung mint cannot stall recovery
98e55f2 to
d676bd9
Compare
…markers - contract-lint job now installs greatspectations, clones cashubtc/nuts HEAD, and runs the check over all non-test sources — DRIFT FAILS THE BUILD (exit-code semantics verified: drifted quote exit 1, clean 0) - critical invocation fix: --comment-start must be "// " (trailing space) — with "//" the marker never matches and the check passes vacuously. make/speccheck.sh (new on this branch; supersedes the version in open OpenTollGate#354 which carries the vacuous-pass bug) documents this in a comment - fixed the one genuinely drifted quote: NUT-03 swap (spec now writes `Proofs` with backticks); 9/9 quotes verified against current spec - added NUT-05 melt-quote at GonutsWallet.Melt (OpenTollGate#299 site) - repaired two comment lines that parsed as malformed markers and aborted whole-repo runs (merchant.go dedup pointer, port.go doc comment)
… fixes) (#376) * fix(spec): fix drifted NUT-03 quote, malformed markers, NUT-05 comment placement - NUT-03 swap quote: 'generate new Proofs' -> 'generate new `Proofs`' (spec added backticks; the one genuinely drifted quote found by review) - NUT-05 melt quote added at GonutsWallet.RequestMeltQuote (per reviewer feedback: above the request-method, not above Melt()) - merchant.go: reword 'NUT-00' marker prefix to 'Spec (NUT 00)' so it doesn't parse as a malformed quote marker - port.go: reword 'NUT-04 spec' to 'spec (NUT 04)' for the same reason - CHANGELOG: note spec-quote drift checking entry superseding #357 - .gitignore: add *.cov to exclude greatspectate coverage artifacts * ci(spec): wire spec-quote drift check with vacuous-pass fix + coverage step - Contract-lint job: new 'Spec-quote drift check' step that installs greatspectations, clones cashubtc/nuts, and verifies all NUT spec quotes in source comments against spec — drift fails the build. - make/speccheck.sh: supports both local drift-report mode and CI fail mode. Vacuous-pass fix: tool/config/usage errors (exit 2+) propagate non-zero; exit 0 only for clean runs or drift-only (exit 1, loud banner). Coverage step folded in from main's #354 but corrected for the real greatspectate CLI (--coverage=FILE). - Correct command name: greatspectations installs 'greatspectate' as its only console script (no 'spectate'). Both CI and local scripts use the correct name. - Correct --comment-start '// ' (trailing space) — without the trailing space the checker passes vacuously (matches nothing). - Pinned deps: greatspectations at SHA 0f226495 with scheduled-bump comment; cashubtc/nuts at SHA 49a909c in CI for reproducibility. - No silenced pip output (install logs visible). --------- Co-authored-by: Felix <301398501+felixfelix-bot@users.noreply.github.com>
…o main) (OpenTollGate#354) * docs: fix stale SSID format comment Update example from old 'TollGate-ABCD-2.4GHz-1' (band suffix) to simplified 'TollGate-A1B2' (random chars only). * feat: add token recovery tool + AI audit prompts + speccheck Token Recovery Tool: Standalone Go tool that recovers Cashu tokens from tokens-to-recover.txt (written when autopay fails with NDS gate errors). Checks proof state at mint via NUT-07 checkstate, recovers unspent tokens via Wallet.Receive(). Supports --dry-run. Also includes: - docs/ai-audit/ — 3 AI audit prompt templates (NUT compliance, security, deps) - make/speccheck.sh — one-command greatspectations spec checking Tested against testnut.cashu.exchange with real tokens. * fix(speccheck): exit 0 after reporting drift Under set -e, a non-zero exit from 'spectate check' (drift found) aborted the script before the coverage report and propagated as the script's exit status. Drift is this script's report, not its failure mode — report and exit 0; infra errors (install/clone) still abort. CI gating can invert this deliberately when wired in. Review findings: cold-code review 2026-08-17 item 3. * fix(token-recovery): unspent-only recovery, single wallet, no secret leak - PENDING proofs were treated as recoverable (state != Spent), so the tool could receive in-flight proofs — double-spend attempt or failed receive. Recoverable now requires State == Unspent for every proof; PENDING gets its own status and a retry-later message. - Wallet loads once per run (lazy, first recoverable token) instead of per line — LoadWallet locks the bolt store, per-token loads contend. - hash_to_curve error no longer prints p.Secret[:16] — proof secrets spend tokens; the slice would also panic on short secrets. - Dry-run counts recoverable tokens separately instead of as ❌ failed. - No timeout change needed: gonuts client already uses a 30s http.Client timeout (wallet/client/client.go:34). Review findings: cold review 2026-08-18 (majors 1-2 + minors 1,2,3*4). * fix: cold review — bound each mint checkstate call with 30s timeout so a hung mint cannot stall recovery * docs: changelog entry for token recovery tool --------- Co-authored-by: Amperstrand <amperstrand@localhost> Co-authored-by: amperstand <atlas@oh-my-opencode.com> Co-authored-by: Felix <301398501+felixfelix-bot@users.noreply.github.com> Co-authored-by: Amperstrand <amperstrand@users.noreply.github.com>
…ith reviewer fixes) (OpenTollGate#376) * fix(spec): fix drifted NUT-03 quote, malformed markers, NUT-05 comment placement - NUT-03 swap quote: 'generate new Proofs' -> 'generate new `Proofs`' (spec added backticks; the one genuinely drifted quote found by review) - NUT-05 melt quote added at GonutsWallet.RequestMeltQuote (per reviewer feedback: above the request-method, not above Melt()) - merchant.go: reword 'NUT-00' marker prefix to 'Spec (NUT 00)' so it doesn't parse as a malformed quote marker - port.go: reword 'NUT-04 spec' to 'spec (NUT 04)' for the same reason - CHANGELOG: note spec-quote drift checking entry superseding OpenTollGate#357 - .gitignore: add *.cov to exclude greatspectate coverage artifacts * ci(spec): wire spec-quote drift check with vacuous-pass fix + coverage step - Contract-lint job: new 'Spec-quote drift check' step that installs greatspectations, clones cashubtc/nuts, and verifies all NUT spec quotes in source comments against spec — drift fails the build. - make/speccheck.sh: supports both local drift-report mode and CI fail mode. Vacuous-pass fix: tool/config/usage errors (exit 2+) propagate non-zero; exit 0 only for clean runs or drift-only (exit 1, loud banner). Coverage step folded in from main's OpenTollGate#354 but corrected for the real greatspectate CLI (--coverage=FILE). - Correct command name: greatspectations installs 'greatspectate' as its only console script (no 'spectate'). Both CI and local scripts use the correct name. - Correct --comment-start '// ' (trailing space) — without the trailing space the checker passes vacuously (matches nothing). - Pinned deps: greatspectations at SHA 0f226495 with scheduled-bump comment; cashubtc/nuts at SHA 49a909c in CI for reproducibility. - No silenced pip output (install logs visible). --------- Co-authored-by: Felix <301398501+felixfelix-bot@users.noreply.github.com>
Rebased version of #340. Conflicts resolved: .gitignore merged both sides, vendor_element_manager.go kept HEAD. 5 commits applied cleanly. Build verified.