Skip to main content

qualia_core_db/modalities/
value_flow.rs

1//! Value-flow & compensation (§23, legal_logic.md) — the Permissive Commons.
2//!
3//! Shifts economic obligation from infinite linear consumption to **threshold-based discharge**
4//! to prevent extraction: a work's cost is its audited production cost plus a *legally capped*
5//! ROI; usage by an agent triggers a royalty scaled by the agent's category; payments accumulate
6//! into a pool; once the pool meets the cost, the obligation is **discharged and the use is freed
7//! globally**. Integer arithmetic throughout (deterministic, zero-heap) — units are abstract
8//! minor units (e.g. cents).
9
10/// Total economic obligation for a work: `production_cost × (1 + roi_cap)`, with the ROI margin
11/// **capped** (the `sh:maxInclusive` cap — extraction guard). `roi_cap_percent` is clamped to
12/// `max_roi_percent` before applying. Saturating.
13pub fn commons_cost(production_cost: u64, roi_cap_percent: u64, max_roi_percent: u64) -> u64 {
14    let roi = roi_cap_percent.min(max_roi_percent);
15    let margin = production_cost.saturating_mul(roi) / 100;
16    production_cost.saturating_add(margin)
17}
18
19/// The royalty a use incurs: `base × multiplier%`, where the multiplier scales by agent
20/// category (e.g. a corporate user pays a higher multiple than a non-profit). Saturating.
21#[inline]
22pub fn royalty(base: u64, agent_multiplier_percent: u64) -> u64 {
23    base.saturating_mul(agent_multiplier_percent) / 100
24}
25
26/// Accumulate a payment into the compensation pool (saturating).
27#[inline]
28pub fn pool_after(pool: u64, payment: u64) -> u64 {
29    pool.saturating_add(payment)
30}
31
32/// The obligation is **discharged** once accumulated compensation meets the cost — the use is
33/// then obligation-free (freed globally). `Active(Outstanding) → Discharged(ObligationFree)`.
34#[inline]
35pub fn is_commons_discharged(pool: u64, cost: u64) -> bool {
36    pool >= cost && cost > 0
37}
38
39/// Outstanding balance still owed before discharge (0 once met). Saturating.
40#[inline]
41pub fn outstanding(pool: u64, cost: u64) -> u64 {
42    cost.saturating_sub(pool)
43}
44
45// ─── Thermodynamic cost caps (E-ROI) ──────────────────────────────────────────────
46
47/// **Energy Return On Investment** = `energy_returned / energy_invested`. `0.0` if nothing was
48/// invested. The physics-bound viability ratio of a value flow.
49pub fn eroi(energy_returned: u64, energy_invested: u64) -> f32 {
50    if energy_invested == 0 {
51        0.0
52    } else {
53        energy_returned as f32 / energy_invested as f32
54    }
55}
56
57/// Is a value flow thermodynamically viable — E-ROI at or above `min_ratio`? Below this floor the
58/// flow is net-extractive (spends more energy than it recovers) and is refused — the physics-bound
59/// cost cap.
60#[inline]
61pub fn eroi_viable(energy_returned: u64, energy_invested: u64, min_ratio: f32) -> bool {
62    eroi(energy_returned, energy_invested) >= min_ratio
63}
64
65// ─── Recursive royalty trees (derivative-work attribution) ────────────────────────
66
67/// The royalty owed to an ancestor `generation` levels up a derivation chain: a geometric split
68/// where each level takes `share_percent` of what reaches it —
69/// `total × (share_percent/100)^(generation+1)`. Generation 0 = the immediate parent. Saturating
70/// integer arithmetic; zero-heap. (Recursive commons attribution for derivative works.)
71pub fn ancestor_royalty(total_royalty: u64, generation: u32, share_percent: u64) -> u64 {
72    let mut amount = total_royalty;
73    for _ in 0..=generation {
74        amount = amount.saturating_mul(share_percent) / 100;
75    }
76    amount
77}
78
79/// Total royalty distributed up a chain of `generations` ancestors (the sum of each generation's
80/// geometric share) — what leaves the deriving work as upstream attribution.
81pub fn royalty_tree_total(total_royalty: u64, generations: u32, share_percent: u64) -> u64 {
82    let mut sum = 0u64;
83    for g in 0..generations {
84        sum = sum.saturating_add(ancestor_royalty(total_royalty, g, share_percent));
85    }
86    sum
87}
88
89// ─── Multi-currency & cross-jurisdictional tax shunting ───────────────────────────
90
91/// Convert `amount` at `rate_micros` (target units per source unit, in millionths — e.g.
92/// `1_500_000` = ×1.5). Saturating (u128 intermediate).
93pub fn convert_currency(amount: u64, rate_micros: u64) -> u64 {
94    ((amount as u128).saturating_mul(rate_micros as u128) / 1_000_000u128) as u64
95}
96
97/// The tax owed on `amount` at `tax_basis_points` (1 bp = 0.01%) — the automated cross-
98/// jurisdictional tax-schema shunt. Saturating (u128 intermediate).
99pub fn apply_tax(amount: u64, tax_basis_points: u64) -> u64 {
100    ((amount as u128).saturating_mul(tax_basis_points as u128) / 10_000u128) as u64
101}
102
103// ─── Liquidity-pool ODE (drainage + replenishment) ────────────────────────────────
104
105/// One discrete Euler step of the liquidity ODE `dL/dt = inflow − drain·L`: constant `inflow`
106/// replenishment minus drainage proportional to the current pool (`drain_percent`% per step).
107/// Saturating; zero-heap. The steady state is `L* = inflow / drain`.
108pub fn liquidity_step(pool: u64, inflow: u64, drain_percent: u64) -> u64 {
109    let drained = pool.saturating_mul(drain_percent.min(100)) / 100;
110    pool.saturating_sub(drained).saturating_add(inflow)
111}
112
113/// Evolve liquidity over `steps` of the ODE (constant `inflow`, proportional `drain_percent`) —
114/// converges toward the steady state `inflow / (drain_percent/100)`.
115pub fn liquidity_after(initial: u64, inflow: u64, drain_percent: u64, steps: u32) -> u64 {
116    let mut pool = initial;
117    for _ in 0..steps {
118        pool = liquidity_step(pool, inflow, drain_percent);
119    }
120    pool
121}
122
123// ─── Usury circuit-breaker (multi-agent token ceiling) ────────────────────────────
124//
125// MULTI_AGENT_PROTOCOL.md's resource-governance guard: an agent's projected spend may
126// run up to — but not past — an agreed budget plus a small overage; breaching the
127// ceiling is *usurious* and the operation is refused (`ERROR_USURY_LIMIT_EXCEEDED`).
128// A hard anti-extraction cap in the same family as the capped ROI and the E-ROI floor
129// above, not a soft warning. Deterministic saturating integer arithmetic.
130
131/// Default permitted overage above an agreed budget, in percent — the spec's **110%**
132/// token ceiling is `budget × (1 + 10/100)`.
133pub const USURY_OVERAGE_PERCENT_DEFAULT: u64 = 10;
134
135/// Maximum spend permitted before the usury breaker trips: `budget × (1 + overage/100)`
136/// (saturating). With the default 10% overage this is the 110% ceiling.
137#[inline]
138pub fn usury_ceiling(budget: u64, overage_percent: u64) -> u64 {
139    let margin = budget.saturating_mul(overage_percent) / 100;
140    budget.saturating_add(margin)
141}
142
143/// Has `projected_spend` breached the usury ceiling for `budget`? Spending *up to and
144/// including* the ceiling is permitted; only a strictly greater spend is usurious.
145#[inline]
146pub fn is_usurious(projected_spend: u64, budget: u64, overage_percent: u64) -> bool {
147    projected_spend > usury_ceiling(budget, overage_percent)
148}
149
150/// `ERROR_USURY_LIMIT_EXCEEDED` — a projected spend breached the agreed budget's
151/// ceiling. Carries the `budget`, the computed `ceiling`, and the offending
152/// `projected` spend so the caller can write a faithful conduct-violation record.
153#[derive(Debug, Clone, Copy, PartialEq, Eq)]
154pub struct UsuryError {
155    pub budget: u64,
156    pub ceiling: u64,
157    pub projected: u64,
158}
159
160/// Gate a projected spend against the usury ceiling — `Ok(())` while at/under the
161/// ceiling, `Err(UsuryError)` once it is breached. The fiduciary circuit-breaker an
162/// agent's resource declaration is checked through before the spend is admitted.
163#[inline]
164pub fn check_usury(
165    projected_spend: u64,
166    budget: u64,
167    overage_percent: u64,
168) -> Result<(), UsuryError> {
169    let ceiling = usury_ceiling(budget, overage_percent);
170    if projected_spend > ceiling {
171        Err(UsuryError {
172            budget,
173            ceiling,
174            projected: projected_spend,
175        })
176    } else {
177        Ok(())
178    }
179}
180
181#[cfg(test)]
182mod tests {
183    use super::*;
184
185    #[test]
186    fn eroi_gates_thermodynamic_viability() {
187        assert!((eroi(300, 100) - 3.0).abs() < 1e-6);
188        assert_eq!(eroi(5, 0), 0.0);
189        // Viable iff E-ROI ≥ floor.
190        assert!(eroi_viable(300, 100, 2.0));
191        assert!(!eroi_viable(150, 100, 2.0), "net-extractive → refused");
192    }
193
194    #[test]
195    fn recursive_royalty_tree() {
196        // 50% per generation: parent gets 50, grandparent 25, great-grandparent 12.
197        assert_eq!(ancestor_royalty(100, 0, 50), 50);
198        assert_eq!(ancestor_royalty(100, 1, 50), 25);
199        assert_eq!(ancestor_royalty(100, 2, 50), 12); // 100*.5*.5*.5 = 12.5 → 12 (integer)
200                                                      // The chain total over 3 generations: 50 + 25 + 12 = 87.
201        assert_eq!(royalty_tree_total(100, 3, 50), 87);
202    }
203
204    #[test]
205    fn multi_currency_and_tax() {
206        assert_eq!(convert_currency(100, 1_500_000), 150); // ×1.5
207        assert_eq!(convert_currency(100, 500_000), 50); // ×0.5
208        assert_eq!(apply_tax(10_000, 250), 250); // 2.5% of 10000
209    }
210
211    #[test]
212    fn liquidity_ode_converges_to_steady_state() {
213        // inflow 100, drain 10%/step → steady state L* = 100 / 0.10 = 1000.
214        let one = liquidity_step(0, 100, 10);
215        assert_eq!(one, 100); // 0 drained + 100 inflow
216        let settled = liquidity_after(0, 100, 10, 500);
217        assert!(
218            (settled as i64 - 1000).abs() <= 1,
219            "converges to inflow/drain = 1000, got {settled}"
220        );
221        // Draining a full pool with no inflow shrinks it.
222        assert!(liquidity_after(1000, 0, 50, 5) < 1000);
223    }
224
225    #[test]
226    fn roi_is_capped() {
227        // 1000 cost, asked-for 50% ROI but cap is 20% → cost = 1000 + 200 = 1200.
228        assert_eq!(commons_cost(1000, 50, 20), 1200);
229        // Within cap → applied as-is.
230        assert_eq!(commons_cost(1000, 10, 20), 1100);
231    }
232
233    #[test]
234    fn royalty_scales_by_agent_category() {
235        // corporate 300% vs non-profit 50% of the same base.
236        assert_eq!(royalty(100, 300), 300);
237        assert_eq!(royalty(100, 50), 50);
238    }
239
240    #[test]
241    fn usury_breaker_trips_past_the_110_percent_ceiling() {
242        // A 1000-token budget admits spend up to the 110% ceiling (1100); past it is usurious.
243        assert_eq!(usury_ceiling(1000, USURY_OVERAGE_PERCENT_DEFAULT), 1100);
244        assert!(check_usury(1000, 1000, USURY_OVERAGE_PERCENT_DEFAULT).is_ok());
245        assert!(
246            check_usury(1100, 1000, USURY_OVERAGE_PERCENT_DEFAULT).is_ok(),
247            "exactly at ceiling is permitted"
248        );
249        assert!(!is_usurious(1100, 1000, USURY_OVERAGE_PERCENT_DEFAULT));
250        let err = check_usury(1101, 1000, USURY_OVERAGE_PERCENT_DEFAULT).unwrap_err();
251        assert_eq!(err.ceiling, 1100);
252        assert_eq!(err.projected, 1101);
253        assert!(is_usurious(1101, 1000, USURY_OVERAGE_PERCENT_DEFAULT));
254        // A zero budget permits no positive spend.
255        assert!(check_usury(1, 0, USURY_OVERAGE_PERCENT_DEFAULT).is_err());
256        assert!(check_usury(0, 0, USURY_OVERAGE_PERCENT_DEFAULT).is_ok());
257        // The overage is a policy knob: a stricter 0% overage caps exactly at budget.
258        assert_eq!(usury_ceiling(1000, 0), 1000);
259        assert!(check_usury(1001, 1000, 0).is_err());
260    }
261
262    #[test]
263    fn pool_discharges_at_threshold() {
264        let cost = commons_cost(1000, 20, 20); // 1200
265        let mut pool = 0u64;
266        pool = pool_after(pool, royalty(400, 300)); // corporate use: 1200
267        assert!(
268            is_commons_discharged(pool, cost),
269            "pool met cost → discharged + freed globally"
270        );
271        assert_eq!(outstanding(pool, cost), 0);
272        // Before that payment the obligation was outstanding.
273        assert!(!is_commons_discharged(500, cost));
274        assert_eq!(outstanding(500, cost), 700);
275    }
276}