From 1d07236c292df55d0ad40fe86880e66eea8ab56c Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 14 Jul 2026 11:02:06 +0000 Subject: [PATCH] =?UTF-8?q?docs:=20commenti=20inline=20sul=20perch=C3=A9?= =?UTF-8?q?=20in=20core/induttivo/lambda=5Fspace?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Il codice era già densamente commentato sul WHY (docstring di modulo e funzione, rationale delle scelte di design). Questa passata aggiunge SOLO i vuoti reali trovati — numeri magici o scelte non ovvie senza motivazione accanto — senza restatement di ciò che è già spiegato altrove: - core.py: perché _to_native esiste (numpy leaks non serializzabili), perché il match testuale argomento↔fallacia (nessun indice condiviso tra Argomento e Patologia, span da passaggi diversi), perché la soglia 0.95 sul warning di bilanciamento Θ/ऋ (euristica non calibrata). - lambda_space.py: perché frozenset per LAMBDA_RESH (immutabilità: Λ evolve a livello di codice, mai per mutazione a runtime), perché _audit_invariants gira eager a import time (fail-fast, non a metà run). - induttivo.py: perché lo sconto ×0.8 sulla confidence dei segnali deterministici reinterpretati come hit Trilemma (inferenza su un pattern nato per altro scopo, non rilevazione diretta), perché arsenale/trilemma restano fuori da `da_eseguire` (hanno blocchi dedicati, non sono saltati). epsilon.py verificato ma non toccato: già il più commentato dei quattro. Zero modifiche di logica — solo commenti, verificato con py_compile e le batterie no-ML esistenti (tutte verdi, invariate). Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_016MnNuFahrz482cFEqCEnoq --- core.py | 13 +++++++++++++ induttivo.py | 8 ++++++++ lambda_space.py | 5 +++++ 3 files changed, 26 insertions(+) diff --git a/core.py b/core.py index 747a05a..46c286a 100644 --- a/core.py +++ b/core.py @@ -86,6 +86,9 @@ def _peso_sequitur() -> float: # ─── helpers numerici ──────────────────────────────────────────────────────── +# NLI/embedding/numpy lasciano scalari e array numpy dentro i dict che finiscono +# in yaml_out → json.dumps si spezzerebbe su np.float32/np.bool_ senza questa +# normalizzazione preventiva (RapportoResh dev'essere serializzabile as-is). def _to_native(obj): if isinstance(obj, dict): return {k: _to_native(v) for k, v in obj.items()} @@ -295,6 +298,12 @@ async def analizza_async( integrita_io, integrita_dett = await _run_in_thread(_valuta_io, teleologia, fonte=obiettivo_fonte) # verifiche logiche: 1 verifica per argomento (fallacia O non-sequitur ⇒ non valido) + # Nessun indice condiviso lega Argomento (dalle proposizioni segmentate) alle + # Patologia (span sul testo grezzo): vengono da passaggi diversi sulla stessa + # frase. Si riallineano ri-cercando il testo dell'argomento nel documento e + # controllando se cade dentro (o poco dopo, +200 char di margine per code + # di frase/punteggiatura) lo span della fallacia — match grossolano ma l'unico + # disponibile senza rifare la segmentazione con offset condivisi. verifiche: list[VerificaLogica] = [] fallacy_spans = [(p.span_char, p.dettaglio.get("fallacia_l2", "?")) for p in fallacie_pats if p.span_char] @@ -415,6 +424,10 @@ async def analizza_async( )) patologie_legacy = [p.as_message() for p in pat_struct] + # Soglia euristica (non calibrata su corpus, come i pesi in epsilon.py): un + # testo con ε quasi perfetto e zero patologie è sospetto quanto uno basso — + # potrebbe segnalare che il dubbio (ऋ) non sta esercitando abbastanza + # resistenza contro la certezza (Θ), non che il testo sia davvero impeccabile. if eps_resh > 0.95: patologie_legacy.append("ε_ऋ molto alto: verificare bilanciamento con Θ (rischio paralisi)") diff --git a/induttivo.py b/induttivo.py index 37974aa..4f0b29e 100644 --- a/induttivo.py +++ b/induttivo.py @@ -330,6 +330,11 @@ def pre_detect_trilemma(testo: str, rapporto_resh=None) -> list[TrilemmaHit]: hits: list[TrilemmaHit] = _scan_markers(testo, _load_trilemma_markers()) # 2. Segnali dal deterministico (se disponibile). + # Sconto ×0.8 sulla confidence: qui si sta REINTERPRETANDO un segnale nato + # per un altro scopo (NON_SEQUITUR/circolarità di sequitur.py) come hit + # Trilemma — un'inferenza su cosa implica il pattern, non una rilevazione + # diretta del corno. Meno affidabile del match regex diretto (_scan_markers), + # quindi pesa meno nel confronto det/ind di _confronta_trilemma. if rapporto_resh is not None: for pat in getattr(rapporto_resh, "patologie_strutturate", []): tipo_val = getattr(pat.tipo, "value", str(pat.tipo)) @@ -706,6 +711,9 @@ def analizza_induttivo( from .lambda_space import G, resolve O = resolve(G.ESTRAI_OBIETTIVO)(testo) # lazy: Λ spina dorsale + # arsenale/trilemma restano fuori da `da_eseguire`: non sono saltati, hanno + # ciascuno il proprio blocco dedicato più sotto (payload/feed diversi dal + # generico _OUT_GENERICO — trilemma riceve pure Arsenale + ऋ¹ come contesto). da_eseguire = assi if assi is not None else [a for a, _ in _ASSI if a not in ("arsenale", "trilemma")] # 2. Arsenale (3 assi + contrasto in una call). diff --git a/lambda_space.py b/lambda_space.py index 0cefb10..17623c6 100644 --- a/lambda_space.py +++ b/lambda_space.py @@ -117,6 +117,9 @@ def __str__(self) -> str: # ─── registry Λ_ऋ ────────────────────────────────────────────────────── +# frozenset, non list/dict: Λ non si muta a runtime — evolve solo aggiungendo +# un Gamma() qui nel codice (nuovo commit), mai con un .add()/.pop() dell'agente +# durante un'analisi. L'immutabilità è la garanzia, non un dettaglio di tipo. LAMBDA_RESH: frozenset[Gamma] = frozenset({ @@ -1004,4 +1007,6 @@ def _audit_invariants() -> None: assert g.eps_feeds == (), f"{g.name}: eps_feeds assegnato ma eps_role={g.eps_role!r}" +# Eseguito a IMPORT time (non lazy): un invariante rotto deve fermare il modulo +# subito, non emergere a metà run quando un core prova a risolvere un γ malformato. _audit_invariants()