Skip to content

docs: add BRC-100 wallet UTXO lifecycle reference - #474

Open
galt-tr wants to merge 2 commits into
mainfrom
claude/wallet-utxo-swim-lane-883882
Open

docs: add BRC-100 wallet UTXO lifecycle reference#474
galt-tr wants to merge 2 commits into
mainfrom
claude/wallet-utxo-swim-lane-883882

Conversation

@galt-tr

@galt-tr galt-tr commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

Program and scope

  • Tracker or issue: none — documentation request
  • Program gate(s) advanced: none
  • Why this change is needed: docs/specs/brc-100-wallet.md describes method shapes but no flow. The lifecycle knowledge was scattered across un-frontmattered engineering notes in packages/wallet/wallet-toolbox/CURRENT_STATE.md (which docs-site does not publish), prose in go-wallet-toolbox/docs/, and one-issue-at-a-time gap docs in go-wallet-toolbox/plans/. Nothing mapped the TypeScript and Go implementations against each other method-by-method: conformance/PARITY_MATRIX.json is language-agnostic (TS vs "other impls"), not TS↔Go.
  • Explicitly out of scope: no source, manifest, dependency, or conformance-vector change. The pre-existing prettier non-conformance of docs/specs/brc-100-wallet.md is left alone (docs/** is not covered by format:root); only the two-line link insertion was made there.
  • Exact head SHA reviewed: see the head of this branch

Impact

  • No public package source or manifest changed
  • Public package source or manifest changed; affected packages are listed below
  • Infrastructure source, dependency, image, or deployment configuration changed
  • Public API, exports, types, runtime targets, or browser/mobile behavior changed
  • Security-sensitive boundary changed
  • Documentation or examples changed

Affected packages/services and intended patch versions: none. No published bytes change.

What the page contains

New docs/architecture/wallet-utxo-lifecycle.md:

  • Swim lanes for createAction, signAction, processAction, funding/coin-selection, internalizeAction, abortAction, and the Monitor. Lanes are consistent across every diagram: App → Wallet → Signer → Manager → Storage → Database → Services → Monitor.
  • A storage call ledger — every storage-interface call each BRC-100 UTXO method makes, in execution order.
  • State machines for transaction status, proof-request status, and output spendability, plus the determineReqTxStatus and broadcast-outcome matrices.
  • The full 28-method inventory in WalletWireCalls order, with lighter diagrams for the crypto, certificate, and wallet-state groups, and a note on the non-BRC-100 helpers both implementations add.
  • Fourteen implementation differences, each stating the BRC-100 requirement first, then TypeScript, then Go — and saying so explicitly where the spec is silent rather than picking a winner.

Two of those differences are behavioral and observable, not cosmetic:

  1. Failed transactions treat spent inputs oppositely. TypeScript releases inputs back to spendable on failed, then re-marks only those the chain positively confirms are gone. Go never releases them, on the reasoning that a missing-inputs verdict can be a false positive. Same event, different resulting balance. BRC-100 does not specify this.
  2. Change becomes spendable at different times. Go promotes change at queue time on the delayed path and at network acceptance on the immediate path; TypeScript sets it at commit and gates visibility through the parent-status join. listOutputs can return different sets for an in-flight transaction.

Also worth reviewer attention: getNetwork returns main/test in Go where the spec requires mainnet/testnet, and Go's V1 storage client returns empty collections with a nil error for findOutputBasketsAuth/findOutputsAuth — indistinguishable from a genuine empty result.

A companion Go-side page is opened separately against bsv-blockchain/go-wallet-toolbox.

Diagram format note

Mermaid fences render on docs-site already — docs-site/src/components/CodeBlock.tsx routes lang === 'mermaid' to the lazy-loaded Mermaid component. No new dependency. This is the first published docs/ page to use one; existing mermaid lives only in unpublished package-local notes.

Verification

  • Local commands and results:
    • pnpm --filter docs-site validateFrontmatter valid: 116 files checked / Links OK: 116 files checked
    • pnpm docs:facts:check → parity matrix verified (75 files, 6681 vectors), stack facts verified, 31 package READMEs, 96 freshness records, 0 findings
    • pnpm --filter docs-site build → 121 pages prerendered, Pagefind indexed, Built links OK: 121 HTML files checked
    • npx prettier --check docs/architecture/wallet-utxo-lifecycle.md docs/architecture/brc-100.md → clean
    • All 17 mermaid blocks across both repos' new pages parsed with mermaid.parse() under jsdom → 0 failed. Confirmed the 13 blocks on this page reach the built chunk (10 sequenceDiagram, 3 stateDiagram-v2).
  • Hosted CI run: pending on this head
  • Conformance evidence: not applicable — no vector or dispatcher change
  • Coverage delta: none — no code changed
  • Lint/typecheck delta: none — no code changed
  • Browser/mobile/packed-consumer evidence: not applicable
  • Performance or bundle-size delta: one additional prerendered page; mermaid was already a docs-site dependency and is lazy-loaded
  • I self-reviewed the complete diff for correctness, security, compatibility, public API, artifacts, dependencies, docs, and operations
  • All applicable checks are terminal and successful on the exact head — pending

Every file:line citation and every claimed difference was read against source in both repositories rather than inferred. The four strongest claims (failed-input handling, the remote-client stubs, the getNetwork values, and the protocol-name minimum) were each confirmed at the exact line, including their in-code rationale comments.

Security and dependencies

  • No dependency or lockfile change
  • Changelog, runtime relevance, peer compatibility, transitive graph, and audit results were reviewed — not applicable, no dependency change
  • CodeQL/negative tests cover any changed trust boundary — no trust boundary changed
  • The exact-head CodeQL analysis has no new alert — pending
  • The exact-head repository quality gate reports zero new Sonar findings — pending
  • No new override, advisory dismissal, quality suppression, or skipped test
  • Any temporary exception is registered — none added
  • Workflow permissions and lifecycle-script behavior remain least privilege — unchanged

Dependency evidence

Not applicable — no dependency change.

Release and operations

  • No npm publication was performed from a workstation or from this PR
  • Required npm patch bumps are included or intentionally deferred — none required, no published bytes change
  • Image/SBOM/provenance/deployment/rollback impact is documented — none
  • Documentation, changelog, migration, and operational guidance are current

Completion evidence

  • The linked tracker is updated only for work fully proved — no tracker
  • Review conversations are resolved — none open
  • Documentation, changelog, migration notes, release notes, and operator guidance are current or concretely not applicable
  • No pending, failed, stale, cancelled, or unexpectedly skipped check is being handed to another contributor as "complete" — CI pending on this head
  • One qualified maintainer approval is sufficient; no last-pusher restriction is assumed

Generated by Claude Code

Documents the full transaction lifecycle across the BRC-100 wallet
interface: every storage-layer call each UTXO method makes, the
transaction and proof-request state machines, output spendability
rules, and the funding/coin-selection pipeline.

Diagrams are mermaid sequence and state diagrams, which docs-site
already renders via CodeBlock -> Mermaid. Lanes are consistent across
every diagram: App, Wallet, Signer, Manager, Storage, Database,
Services, Monitor.

Covers both @bsv/wallet-toolbox and go-wallet-toolbox, with the
BRC-100 spec as the reference for both, and collects fourteen
implementation differences -- including two behavioral divergences
that are not specified by BRC-100 and produce different observable
results: failed transactions release spent inputs in TypeScript but
not in Go, and change becomes spendable at different points in the
broadcast flow.

Linked from docs/architecture/brc-100.md and docs/specs/brc-100-wallet.md.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Lug8S7eE3uxTFRtr5pU9kw
@galt-tr
galt-tr requested a review from sirdeggen as a code owner August 13, 2026 11:57
The page claimed reorg handling, double-spend review, and broadcaster
push events were absent in go-wallet-toolbox. They are not. It compared
TypeScript's nineteen registered monitor tasks against Go's four and
read the difference as missing behavior, when Go moves most of that work
off the scheduler:

- pkg/monitor runs an SSE broadcast-event pipeline with a persisted
  replay cursor, plus reorg and new-tip consumers. Provider.HandleReorg
  invalidates merkle proofs for orphaned blocks -- event-driven, not
  polled.
- confirmDoubleSpends re-verifies every aggregated double-spend verdict
  inline before it becomes terminal, downgrading false positives to
  serviceError for retry.

What Go genuinely does not reproduce is the reviewStatus cascade, plus
purge and action-batch cleanup. The section now says that and explains
the two mechanisms, rather than counting scheduled tasks.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Lug8S7eE3uxTFRtr5pU9kw
@sonarqubecloud

Copy link
Copy Markdown

galt-tr commented Aug 13, 2026

Copy link
Copy Markdown
Contributor Author

CI is red on c132d15, and it is not this PR. Flagging rather than fixing, because the remediation is a dependency change and this is a documentation-only branch.

Root cause — one failure, three cascades. Build, lint, and policy fails at pnpm audit --audit-level=high:

high  nanoid: custom generators can loop indefinitely when size is zero
Vulnerable versions  <3.3.18
Paths                .>vite>postcss>nanoid
More info            https://github.com/advisories/GHSA-2v37-7h3g-55p8
3 vulnerabilities found. Severity: 3 high (2 ignored)

build-and-test (24.x), Mutation quality and merge-gate then fail on PREPARE_RESULT: failure with every other lane skipped — they never ran anything.

Why it isn't this branch. The full diff against main is one markdown file:

docs/architecture/wallet-utxo-lifecycle.md | 26 +++++++++++++++++++-------

No package.json, no pnpm-lock.yaml, no pnpm-workspace.yaml. pnpm audit is a function of the lockfile (unchanged) and the advisory database (time-varying). The same job passed on this branch at 12:00Z on 3b859b5; it failed at 19:17Z on c132d15, whose only change is prose. The advisory landed in between.

main last ran CI on 2026-08-12 at 7647407c and was green, so there is no red main run to point at yet — but this will fail on main and on every open PR the moment any of them next runs.

Not fixing it here. nanoid is transitive under vite > postcss, so remediation is an override or a vite/postcss bump plus a lockfile change. Per AGENTS.md that needs its own review evidence — release notes, peer compatibility, transitive graph, audit — and an override would need a governed registry entry with owner, evidence, review date, and removal condition. None of that belongs in a docs PR, and a generic dependency bump is explicitly not a reason to widen scope.

Happy to open a separate PR for the bump if a maintainer wants it. Otherwise this branch should go green once the advisory is remediated on main and this PR is updated from it.


Generated by Claude Code

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.

3 participants