Skip to content

SPEC 010 Wallets Allocation

Rafael Queiroz edited this page Sep 12, 2026 · 3 revisions

SPEC-010 — Wallets & Allocation

Status Draft
PRD source F4 (FR-4.6–4.27), DM-2
Depends on SPEC-006 (ledger), SPEC-007 (positions)
Required by SPEC-011 and all report specs, SPEC-017, SPEC-019, SPEC-020
Milestone M3

Description

Wallets: purpose-based groupings that cut across brokers and asset classes, so the money saved for retirement can be measured separately from everything else. This is the product's central differentiating idea — no broker models it.

Two design rules shape the whole feature.

Allocation defaults to the whole position and stays that way by itself. The common case is that an asset belongs entirely to one wallet — the dividend payers are all retirement money. So assignment is one click that takes the full position, and subsequent purchases flow into the same wallet automatically. A user should never have to revisit a wallet after buying more of something already in it.

Where the answer is ambiguous, the system stops rather than guesses. Once an asset is deliberately split across two wallets, a new purchase could serve either purpose, and the existing split is evidence of nothing. Distributing it proportionally would invent an intention the user never expressed and quietly erode the separation they took trouble to create.

Business rules

Model

ID Rule
BR-010-01 A user can create, rename, describe, colour and delete wallets.
BR-010-02 A wallet may record a stated goal. Descriptive through M6; amended by SPEC-019 at M7, where a wallet goal becomes a measured amount and this text becomes the goal’s name (SPEC-019 DL-019-06).
BR-010-03 Assigning an asset to a wallet allocates the entire held quantity by default. The user confirms with one click, not by typing a number.
BR-010-04 Allocation is nonetheless stored by quantity, so a position can be split deliberately: 100 ITSA4 as 60 Retirement / 40 Trading. Splitting is always an explicit action.
BR-010-05 Total allocated quantity per (user, asset) may never exceed the quantity held, enforced at write time (DM-2).
BR-010-06 Unallocated quantity sits in an implicit Unassigned bucket, always visible so nothing hides.
BR-010-07 Deleting a wallet returns its allocations to Unassigned. It never deletes transactions.
BR-010-08 Wallets are views over the single ledger. A transaction is never duplicated to belong to a wallet.

Allocation workflow

ID Rule
BR-010-09 Assignment is available from the holdings screen, the wallet screen, and the post-import reconciliation screen.
BR-010-10 Buys auto-increment only for single-wallet assets. A purchase of an asset allocated to exactly one wallet adds the full purchased quantity to that wallet with no user action.
BR-010-11 A purchase of an asset allocated across more than one wallet is never auto-allocated. The quantity goes to Unassigned and is raised for the user. It is not distributed proportionally, and intent is not inferred from the existing split.
BR-010-12 Purchases awaiting allocation appear in the same "Needs attention" queue used for unclassified imports, and on the post-import summary and dashboard until resolved.
BR-010-13 Allocating a pending purchase is one action from that queue: pick a wallet, or split deliberately. Quantity is pre-filled with the full purchased amount.
BR-010-14 A user may optionally set a standing rule per asset directing all future purchases to one named wallet. Opt-in, off by default; when set it is the user's instruction, not an inference, and BR-010-11 no longer applies to that asset.
BR-010-15 Auto-allocation is reported, never silent: the post-import summary lists every allocation made and every purchase left pending, each reversible or resolvable there.
BR-010-16 An asset entering the portfolio for the first time lands in Unassigned. The system never guesses which wallet a brand-new holding belongs to.
BR-010-17 Sales reduce allocations proportionally across wallets holding the asset, unless the user specifies which wallet sold. A sale is not symmetric with a purchase: the position has already shrunk, so allocations must come down or they would violate BR-010-05. Deferring would break the invariant.
BR-010-18 Splits, grupamentos and bonificações adjust allocated quantities by the same ratio as the position, preserving each wallet's proportional share. These are mechanical adjustments, not new intent, so no decision is required.

Reporting

ID Rule
BR-010-19 All four reports run at portfolio scope or at any wallet's scope.
BR-010-20 Wallet is available as a grouping dimension in portfolio-scoped reports (SPEC-011).
BR-010-21 Wallets can be compared side by side on performance and composition.
BR-010-22 Wallet-scoped cash flows for return calculation derive from allocated quantities and their cost basis at time of allocation.

Acceptance Criteria

  • Wallets can be created, renamed, described, coloured and deleted.
  • Assigning an asset takes the full held quantity in one click with no quantity typed.
  • A position can be split deliberately across two wallets by explicit action.
  • Allocating more than the held quantity is refused at write time.
  • Unassigned is visible and its quantities are correct.
  • Deleting a wallet returns allocations to Unassigned and deletes no transactions.
  • Buying more of a single-wallet asset auto-increments that wallet with no user action.
  • Buying more of an asset split across two wallets allocates nothing — the quantity lands in Unassigned and appears in "Needs attention".
  • The post-import summary lists both auto-allocations made and purchases left pending.
  • A pending purchase can be resolved in one action with quantity pre-filled.
  • A standing per-asset rule, once set, directs future purchases even for a split asset.
  • The standing rule is off by default.
  • A brand-new holding lands in Unassigned, never in a wallet.
  • A sale reduces allocations proportionally and never leaves allocations exceeding holdings.
  • A sale with a specified wallet reduces only that wallet.
  • A 1:2 split doubles allocated quantities in every wallet and preserves each share.
  • Every report runs at wallet scope with the rest of the portfolio excluded.
  • Grouping by wallet at portfolio scope includes Unassigned and sums to the portfolio total.
  • Marina's acceptance path: six dividend payers assigned in six clicks; next import auto-allocates five of them; the sixth (deliberately split) waits in "Needs attention".

Out of Scope

  • Target allocations, rebalancing suggestions or drift alerts (PRD Q6) — edges toward advice.
  • Nested wallets or wallet hierarchies.
  • Sharing wallets between users.
  • Goal tracking, projections or "will I reach my number" calculations — the goal field is descriptive only.
  • Automatic assignment by rule on asset class, sector or ticker pattern beyond the per-asset standing rule.
  • Wallet-level cash balances or contributions independent of holdings.
  • Transaction-level wallet tagging — allocation is on quantity, not on transactions.

Decision Logs

# Decision Alternatives considered Rationale
DL-010-01 Assignment defaults to the full position. Ask for a quantity every time Splitting is the exception, not the rule. Requiring a number for the common case is friction on every single assignment, and the number is almost always "all of it".
DL-010-02 Auto-increment on buy, for single-wallet assets only. Never auto-increment; always auto-increment Never auto-incrementing means revisiting a wallet after every purchase — the tracker becomes a chore. Always auto-incrementing requires guessing for split assets, which DL-010-03 rejects. Restricting it to the unambiguous case gets the convenience without the guess.
DL-010-03 Split assets are never auto-allocated. Distribute new purchases proportionally to the existing split An existing 60/40 split is evidence of a past decision, not a future one. Buying more ITSA4 could be adding to retirement or to the trade. Proportional distribution invents intent and quietly erodes exactly the separation the user built the split to create.
DL-010-04 Opt-in standing rule as the escape hatch. Leave split assets always manual Without it, a user who splits one asset pays a manual tax forever. A rule the user explicitly sets is their instruction, not the system inferring — which keeps DL-010-03 intact.
DL-010-05 Sales reduce proportionally; purchases do not. Make sales also wait for a decision Deliberately asymmetric. A sale has already happened — the position shrank, and allocations must come down or they exceed holdings (BR-010-05). The system has no option to defer. Proportional is the least-surprising forced choice, with an override available.
DL-010-06 Allocation by quantity, not by transaction tagging. Tag each transaction with a wallet Tagging cannot express "60 of my 100 shares are retirement" without splitting historical transactions, which corrupts the ledger. Quantity allocation keeps the ledger untouched and wallets as pure views.
DL-010-07 Unassigned is an implicit bucket, always visible. Force every holding into a wallet; hide unallocated Forcing allocation blocks import until the user makes decisions they may not be ready for. Hiding it means the wallet views silently fail to sum to the portfolio — the "every number is explainable" principle forbids it.
DL-010-08 Corporate events adjust allocations without asking. Route them to "Needs attention" like purchases A split is not new intent — the user's economic position and its purpose are unchanged, only the share count moved. Asking would be noise.

Clone this wiki locally