Commit 699356a
authored
feat: Universal Quantity Type System (ADR-0013) and Dynamic Asset Registry (ADR-0014) (#196)
* docs: Add ADR-0013 for generic asset and quantity type system
Proposes Quantity[U] generic type to enable multi-asset ledger
with compile-time unit safety. This ADR documents the architectural
decision to evolve from fiat-only Money types to a universal asset
abstraction supporting kWh, GPU-hours, carbon credits, and more.
Key decisions:
- Generic Quantity[U] with Unit interface constraint
- Compile-time prevention of cross-type arithmetic (GBP + kWh)
- Runtime validation for same-type unit mismatch (GBP + USD)
- Rate[From, To] type for temporal pricing/valuation
- Migration path from existing Money implementations
Enables roadmap items:
- Task 9: Asset Agnosticism
- Task 10: Market Data & Valuation (Temporal Pricing Engine)
* chore: Add date and Go version context to Claude Code review prompt
Clarifies that the current date is December 2025+ and Go 1.25 is the
stable release, preventing false positives when reviewing code that
references these versions.
* docs: Clarify that unit types are extensible examples
The Unit interface is open for extension - tenants can define any
custom asset class (air miles, water usage, bandwidth, tokens, etc.)
without modifying the core library. Updated type hierarchy diagram
and package structure to emphasize this extensibility.
* docs: Replace energy examples with loyalty points in ADR-0013
Swaps EnergyUnit for LoyaltyUnit as the primary non-fiat example.
Loyalty points are more universal (airlines, retail, gaming) and
don't tie the ADR to a specific vertical.
Examples now use:
- Currency (fiat) + LoyaltyUnit (points/miles) as primary examples
- TokenUnit, CarbonUnit, ComputeUnit as additional possibilities
* docs: Rewrite ADR-0013 with RBC framework and comprehensive use cases
Major rewrite to capture the full vision of the Universal Asset Bank:
- Introduces RBC pattern (Read, Bill, Collect) as unifying framework
- Documents target use cases: Energy, Compute, Advertising, Logistics,
Derivatives, Carbon, Crypto, Loyalty
- Adds TimestampedQuantity for handling unreliable telemetry
(out-of-order, duplicates, gaps, estimated vs actual)
- Documents pluggable ValuationProvider architecture
- Includes Rate type with temporal validity for time-varying pricing
- Adds design considerations for complex domains (Greeks, tariffs, etc.)
This positions Meridian as a high-integrity transaction engine for any
time-sensitive, complex-valuation asset class.
* docs: Reframe ADR-0013 around Position/Valuation model
Removes the RBC acronym in favor of a cleaner abstraction:
- Position Keeping: Track quantities in native units (asset-agnostic)
- Valuation: Convert positions to settlement currency (pluggable)
Key insight: Fiat is the degenerate case where valuation = identity.
The ledger doesn't need to understand tariff curves or option Greeks -
it just routes to the appropriate valuation provider.
This framing:
- Doesn't box us into specific verticals (energy, compute, etc.)
- Emphasizes the abstraction power of what we've built
- Makes clear that complexity lives in valuation providers, not the ledger
- Shows fiat banking as a special case, not the primary use case
* docs: Remove task number references from ADR-0013
* docs: Add wire format and persistence notes to ADR-0013
Two critical implementation details:
1. Protocol Buffer (Wire Format):
- Generic AssetAmount message avoids recompile/redeploy per asset type
- Adapter layer validates asset_code matches expected type at runtime
2. Database Persistence (GORM):
- Composite columns (amount, unit_code) enable SQL aggregation
- Custom Scanner/Valuer for generic type hydration
- Type safety enforced at application layer, not database
* docs: Replace ASCII art with Mermaid diagrams in ADR-0013
* refactor: Adopt 3-layer Dimensional Hybrid pattern for asset types
Separates Physics (compile-time) from Policy (runtime):
- Layer 1: Dimensions (Monetary, Commodity) as empty struct constraints
- Layer 2: Definitions (UnitDef) loaded from Asset Registry at runtime
- Layer 3: Context (PositionKey attributes) for fungibility nuances
This enables SaaS scalability - tenants define new assets without code
deployment while preserving compile-time dimensional safety.
* feat: Add ADR-0014 for Dynamic Asset Registry & Lifecycle
Defines the runtime asset definition system that enables:
- Tenant-defined assets without code deployment
- Schema-on-Write validation using JSON Schema
- Version lifecycle with explicit deprecation
- Migration-as-Trade pattern preserving audit trails
Complements ADR-0013's compile-time Dimensional Hybrid pattern.
* docs: Update ADR index with new quantity type ADRs
Add ADR-0013 (Universal Quantity Type System) and ADR-0014 (Dynamic
Asset Registry & Lifecycle) to the index and categories. Remove
"Multi-Currency Decimal Precision" from future ADRs as it's now
addressed by ADR-0013.
* docs: Address CodeRabbit review feedback on ADRs
ADR-0013 changes:
- Add rate resolution semantics (overlap handling, gaps, nil bounds)
- Firm up Protocol Buffer decision language with explicit error taxonomy
- Document Scanner validation contract and failure semantics
ADR-0014 changes:
- Expand adapter error handling with explicit gRPC code taxonomy
- Add idempotency guarantees to bulk migration with cursor-based resumption
- Document cache invalidation strategy (timing, scope, distributed coordination)
- Clarify tenant isolation with context propagation details
- Add architectural boundary diagram showing ADR-0013/0014 integration
* docs: Clarify FX valuation is temporal, not identity
Cross-currency fiat (USD → GBP) requires FX rate lookup at a specific
timestamp - it's temporal pricing just like energy tariffs. Only
same-currency fiat uses identity valuation.
---------
Co-authored-by: Ben Coombs <[email protected]>1 parent 90e5711 commit 699356a
File tree
4 files changed
+1064
-1
lines changed- .github/workflows
- docs/adr
4 files changed
+1064
-1
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
76 | 76 | | |
77 | 77 | | |
78 | 78 | | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
79 | 84 | | |
80 | 85 | | |
81 | 86 | | |
| |||
0 commit comments