v3 : socle Rust (moteur pur, accès trustinWallet, serveur) ; maquette Nuxt rangée dans maquette/

- crates/ld-engine : formule inertielle (parité avec la maquette, garde C),
  coquille / changement de fond, assistant d'édition à règles, composition
  d'un document sous vote permanent (adoptions, aperçus, rivales).
- crates/trustin-access : qui voit, qui ouvre, qui gère les accès.
- crates/ld-server : API axum + SQLite, connexion Ğ1 (client OAuth2 de
  connect.monnaie-libre.fr), invitations, entrée en vigueur automatique,
  signalements de contradiction, traductions éditoriales, publication git,
  taille de la toile lue sur la chaîne.
- seeds/acte-engagement-certification.json : 33 articles, fr + en + es ;
  en vigueur : préambule, E1, E2 (seed a minima).
- maquette/ : frontend, backend et docker v2 déplacés tels quels.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Yvv
2026-10-21 02:04:42 +02:00
co-authored by Claude Opus 5.5
parent 4b1732916d
commit 67ddee28b2
275 changed files with 8979 additions and 0 deletions
+107
View File
@@ -0,0 +1,107 @@
"""Parse mode-parameter strings into structured dicts.
A mode-params string encodes voting formula parameters in a compact format.
Example: ``"D30M50B.1G.2T.1"``
Supported codes:
D = duration_days (int)
M = majority_pct (int, 0-100)
B = base_exponent (float)
G = gradient_exponent (float)
C = constant_base (float)
S = smith_exponent (float)
T = techcomm_exponent (float)
N = ratio_multiplier (float)
R = ratio_mode (bool, 0 or 1)
Values may start with a dot for decimals < 1, e.g. ``B.1`` means base_exponent=0.1.
"""
from __future__ import annotations
import re
# Ordered list of recognised codes and their target keys + types
_CODES: dict[str, tuple[str, type]] = {
"D": ("duration_days", int),
"M": ("majority_pct", int),
"B": ("base_exponent", float),
"G": ("gradient_exponent", float),
"C": ("constant_base", float),
"S": ("smith_exponent", float),
"T": ("techcomm_exponent", float),
"N": ("ratio_multiplier", float),
"R": ("is_ratio_mode", bool),
}
# Regex: a single uppercase letter followed by a numeric value (int or float,
# possibly starting with '.' for values like .1 meaning 0.1)
_PARAM_RE = re.compile(r"([A-Z])(\d*\.?\d+)")
def parse_mode_params(params_str: str) -> dict:
"""Parse a mode-params string into a parameter dict.
Parameters
----------
params_str:
Compact parameter string, e.g. ``"D30M50B.1G.2T.1"``.
Returns
-------
dict
Keys present depend on codes found in the string. Defaults are
applied for any code not present::
{
"duration_days": 30,
"majority_pct": 50,
"base_exponent": 0.1,
"gradient_exponent": 0.2,
"constant_base": 0.0,
"smith_exponent": None,
"techcomm_exponent": None,
"ratio_multiplier": None,
"is_ratio_mode": False,
}
Raises
------
ValueError
If an unrecognised code letter is found.
"""
defaults: dict = {
"duration_days": 30,
"majority_pct": 50,
"base_exponent": 0.1,
"gradient_exponent": 0.2,
"constant_base": 0.0,
"smith_exponent": None,
"techcomm_exponent": None,
"ratio_multiplier": None,
"is_ratio_mode": False,
}
if not params_str or not params_str.strip():
return dict(defaults)
result = dict(defaults)
for match in _PARAM_RE.finditer(params_str):
code = match.group(1)
raw_value = match.group(2)
if code not in _CODES:
raise ValueError(f"Code de parametre inconnu : '{code}'")
key, target_type = _CODES[code]
if target_type is int:
result[key] = int(float(raw_value))
elif target_type is float:
result[key] = float(raw_value)
elif target_type is bool:
result[key] = float(raw_value) != 0.0
return result