Skip to content

Commit 699356a

Browse files
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

4 files changed

+1064
-1
lines changed

.github/workflows/claude-code-review.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,11 @@ jobs:
7676
REPO: ${{ github.repository }}
7777
PR NUMBER: ${{ github.event.pull_request.number }}
7878
79+
IMPORTANT CONTEXT:
80+
- Current date: December 2025 or later
81+
- Go version: This project uses Go 1.25+ which is the current stable release
82+
- Do not flag Go version references (like "Go 1.25") as errors or future versions
83+
7984
Please review this pull request and provide feedback on:
8085
- Code quality and best practices
8186
- Potential bugs or issues

0 commit comments

Comments
 (0)