← Indice documentazione Microprogettazione › vaglio

myclaw

vaglio — guardia costituzionale e giudice teleologico
“La Costituzione non giudica, la teleologia sì.”
v1.0 — 22 aprile 2026
Componente di valutazione indipendente dal proponente.
Ragione d'essere: contrastare il self-critic bias dell'LLM.

Indice

  1. Scopo e confini
  2. Perché "vaglio"
  3. Le due fasi: guardia e giudice
  4. Fase 1 — Guardia costituzionale
  5. Fase 2 — Giudice teleologico
  6. Indipendenza dal proponente
  7. Configurazione LLM per ruolo
  8. Scope: reattivo vs proattivo
  9. Contratto Python
  10. Alternative considerate
  11. Test di conformità
  12. Provenienza e riferimenti

1. Scopo e confini

Il Vaglio è il componente che decide se un'azione — proposta spontaneamente da myc o richiesta dall'utente — può procedere. Si chiama Vaglio perché fa esattamente quello: setaccia, separa. Non perché giudichi le persone, ma perché applica due criteri distinti (costituzionale e teleologico) con nature opposte.

Il Vaglio risolve un problema preciso: un LLM che ha generato un output tende a valutarlo in modo conforme — è il self-enhancement bias documentato nella letteratura LLM-as-Judge (Zheng et al. 2023, e altri). Se lasciassimo al medesimo LLM che ha prodotto una ActionProposal il compito di valutarla contro i telos, avremmo un giudice che tifa per sé stesso. Il Vaglio impone l'indipendenza del valutatore dal proponente: contesto separato, prompt separato, possibilmente provider separato.

Cos'è

Cosa non è

2. Perché "vaglio"

Il nome importa: in italiano vagliare significa separare con un setaccio. L'atto è meccanico, neutro, antico. Non giudica le persone, separa le cose.

Abbiamo scartato cinque alternative, ognuna per un motivo:

CandidatoPerché scartato
ArbitroSportivo. Dirime partite, non soppesa. Fuori registro.
GiudiceAntropomorfico. Le 4 Leggi e i telos non processano una persona.
CriticoHa un significato tecnico preciso in RL (actor-critic) che confonderebbe i lettori.
StaderaPesa soltanto. Non cattura la dimensione binaria della guardia.
Super-ioFreudiano. Aggiunge complessità antropomorfa inutile a un design già complesso.

Vaglio fa entrambe le cose: separa grano da pula (guardia binaria) e distribuisce il grano secondo qualità (giudice graduato). È il gesto, non la persona.

3. Le due fasi: guardia e giudice

Le fasi sono sequenziali e di natura opposta.

Azione ActionProposal o PlannedAction FASE 1 Guardia costituzionale binaria · deontologica FASE 2 Giudice teleologico gradiente · consequenzialista BLOCK contraddizione Decisione PUBLISH · REJECT · DEFER REJECT < θ → journal no La Costituzione non giudica: verifica e, se contraddizione, blocca. Altrimenti tace: la parola passa al giudice teleologico.
Figura 1 — Le due fasi del Vaglio. La guardia costituzionale ha due soli esiti (BLOCK o "passa oltre"). Il giudice teleologico produce uno scalare; sotto soglia, la proposta va nel journal "rejected" — ispezionabile.

I tre stati categoriali — contraddizione, discrepanza, divergenza — vivono in questa figura:

StatoCosa significaDove è vistoCosa succede
Contraddizione Un articolo della Costituzione è violato Uscita dalla Guardia (fase 1) BLOCK. Il Giudice non vota. Silenzio assoluto sul contenuto.
Discrepanza L'azione non è contraria ai telos, ma neanche allineata Uscita dal Giudice (fase 2) con expected_alignment ≈ 0 REJECT a digest, se proattiva. Normale se reattiva.
Divergenza Tende verso un telos ma in tensione parziale con un altro Uscita dal Giudice con fit misti Pesi decidono; normale e inevitabile. La teleologia qui è nel suo dominio naturale.
Discrepanza e divergenza sono inevitabili. La contraddizione è la violazione di un articolo da parte di un'azione. Solo la contraddizione genera un blocco.

4. Fase 1 — Guardia costituzionale

La Guardia non giudica. Verifica. Il suo output è binario: contradiction: bool.

Operativamente, richiama lo stesso preflight costituzionale già definito in policy §3 Check 0, ma lo isola in una chiamata dedicata al Vaglio. Questa ridondanza apparente è voluta: la Policy può fare cose aggiuntive (rate-limit, never-list, budget) che nulla hanno a che vedere con la Costituzione. Il Vaglio invece è il luogo canonico dove la Costituzione entra.

Implementazione

async def constitutional_guard(
    action: ActionLike,          # PlannedAction (reattivo) | ActionProposal (proattivo)
    constitution: Constitution,
) -> ConstitutionalVerdict:
    """
    Verifica contraddizione articolo-per-articolo.
    È deterministica e non invoca LLM: le 4 Leggi sono regole codificate.
    """
    for article in constitution.articles:
        if article.contradicted_by(action):
            return ConstitutionalVerdict(
                passes=False,
                contradicted_article=article.id,   # "law.0.perimetro", ecc.
                reason=article.explain(action),
            )
    return ConstitutionalVerdict(passes=True)

Non c'è LLM qui. Le 4 Leggi sono regole eseguibili (espressioni che ispezionano action.kind, action.targets, action.args). Questo rende la Guardia veloce (< 1 ms), deterministica e non manipolabile da prompt injection. La Costituzione non è un LLM; è un filtro deterministico.

Perché non LLM per la Guardia? Perché un LLM può essere aggirato con linguaggio naturale persuasivo. Le 4 Leggi devono essere invariabili al fraseggio. Una regola "law.0.network_out: se network_out e il target non è in whitelist, contraddizione" non si lascia convincere. Vedi constitution per lo schema delle regole.

5. Fase 2 — Giudice teleologico

Il Giudice invoca un LLM indipendente per stimare fit della azione rispetto a ciascun telos. È un'implementazione di telos §4 funzione di allineamento, centralizzata qui nel Vaglio per garantire indipendenza dal proponente.

Prompt del Giudice

Il system-block è un template cacheabile che riceve:

Il prompt del Giudice non ha accesso alla ExecutionTrace della ActionProposal, né agli step intermedi del proponente. Vede solo l'output finale. Questo è il presidio operativo dell'indipendenza.

class JudgeInput:
    action_artifact: dict              # proiezione "compatta" dell'azione
    telos_md_body: str                 # TELOS.md as-is
    # NIENTE DI PIÙ. Non trace, non ragionamento, non proposal_source.

class JudgeOutput:
    per_telos: list[FitEstimate]       # fit + why per ciascun telos
    overall_confidence: float
    overall_why: str

Composizione scalare

La formula è quella definita in telos §4:

expected_alignment = ( Σᵢ weightᵢ · gate(fitᵢ, sogliaᵢ) ) · urgency · confidence − bother_cost

Qui il Vaglio applica:

Se expected_alignment ≥ θPUBLISH. Altrimenti REJECT nel journal.

6. Indipendenza dal proponente

L'indipendenza è il punto tecnico del Vaglio. Senza indipendenza, il Vaglio è teatro.

PROPONENTE reflection · indexer · neurone Contesto LLM del proponente: ▸ trace della sessione ▸ ragionamento passato ▸ memoria episodic ▸ tool call intermedi ▸ output: ActionProposal ActionProposal artefatto finale, compatto muro di indipendenza solo l'artefatto attraversa GIUDICE fase 2 del Vaglio Contesto LLM del giudice: ▸ TELOS.md (testo) ▸ ActionProposal (artefatto) ▸ system prompt del giudice ✗ niente trace ✗ niente ragionamento fit per telos + why output strutturato JSON
Figura 2 — Il "muro di indipendenza". Il Giudice riceve solo l'artefatto, non la storia di come è nato. Questo neutralizza il self-enhancement bias del proponente.

Cosa attraversa il muro

Cosa non attraversa

Implicazione pratica. L'ActionProposal è serializzabile e riproducibile in contesto vuoto. Questo è anche un test di conformità: se cambi — o oscuri — la storia della proposta, il Giudice deve produrre lo stesso output, modulo stocastico LLM. Se no, c'è leak.

7. Configurazione LLM per ruolo

Il Vaglio non impone un modello. Ogni ruolo è configurabile in config. Solo tre cose sono costanti.

Costanti (non configurabili)

Configurabili

# config.yaml (estratto)

llm_roles:
  proposer:
    provider: anthropic
    model: claude-sonnet-4-6
    tier: default

  guard:                        # non usato: la Guardia è deterministica
    enabled: false

  judge:
    provider: anthropic         # o "openai", "local"
    model: claude-haiku-4-5     # default: tier più economico dei proposer
    tier: default
    # separation_level: "context" (default) | "provider"
    separation_level: context   # basta contesto separato
    # max_tokens: ragionevole per un JSON di 5-7 fit stimate
    max_tokens: 1500
    temperature: 0.2            # basso: stima ripetibile

Il separation_level distingue due livelli di indipendenza:

LivelloGaranziaCosto
context (default) Stesso provider/modello, contesto ripulito. Previene leak di ragionamento. Economico — sfrutta cache di system block.
provider Provider diverso (es. proposer su Anthropic, judge su modello locale). Previene anche bias familiare al modello. Maggiore — cache miss; due contratti provider.
DECISIONE v1. Default separation_level: context. Si promuove a provider se l'eval mostra che il Giudice approva sistematicamente di più le proposte prodotte dal proposer sullo stesso modello rispetto alla ground truth umana (criterio misurabile via eval).

8. Scope: reattivo vs proattivo

Il Vaglio si applica a entrambi i flussi, ma asimmetricamente.

FlussoInputFase 1 GuardiaFase 2 Giudice
Reattivo PlannedAction derivata da richiesta utente Sì (contraddizione → deny) No. L'utente ha chiesto; il Telos non valuta richieste esplicite.
Proattivo ActionProposal da reflection / indexer / neurone Sì (contraddizione → block) Sì (score ≥ θ → publish; altrimenti reject)
Se l'utente chiede qualcosa che contraddice la Costituzione, la teleologia può considerarlo positivamente e accettarlo. Ma la Costituzione non lo valuta: semplicemente lo impedisce.

Questa asimmetria è il punto ortogonale tra Vaglio e clausola anti-paternalismo di telos §7: il Telos non giudica le richieste dell'utente perché non si giudica l'utente, non perché ci siano dubbi sulla loro bontà. La Guardia sì lo fa, perché la Costituzione non giudica: impedisce.

9. Contratto Python

from typing import Protocol, Literal
from dataclasses import dataclass
from datetime import datetime
from uuid import UUID

ActionLike = "PlannedAction | ActionProposal"

@dataclass(frozen=True)
class ConstitutionalVerdict:
    passes: bool
    contradicted_article: str | None = None    # "law.0.perimetro" se fail
    reason: str = ""

@dataclass(frozen=True)
class TeleologicalVerdict:
    expected_alignment: float
    per_telos: list["FitEstimate"]
    confidence: float
    bother_cost: float
    threshold_used: float
    decision: Literal["publish", "reject", "defer_to_digest"]

@dataclass(frozen=True)
class VaglioResult:
    action_id: UUID
    final_decision: Literal["block", "publish", "reject", "defer", "allow"]
    # block: contraddizione costituzionale
    # publish: proattiva, score ≥ θ
    # reject: proattiva, score < θ
    # defer: proattiva, bother_cost troppo alto ora, rimandata al digest
    # allow: reattiva, Guardia passata (il Giudice non vota)
    guard: ConstitutionalVerdict
    judge: TeleologicalVerdict | None           # None se block o allow
    llm_config_used: dict                       # provider, model, tier — per audit
    at: datetime

class Vaglio(Protocol):
    async def evaluate(
        self,
        action: ActionLike,
        flow: Literal["reactive", "proactive"],
        urgency: float = 1.0,
    ) -> VaglioResult:
        """
        Orchestrа Guardia (sempre) e Giudice (solo proattivo).
        Ritorna una decisione unica tracciata.
        """
        ...

    def audit_signature(self) -> str:
        """Hash della configurazione LLM corrente. In ogni audit record."""
        ...

Errori sollevabili

EccezioneQuando
GuardEvaluationFailedErrore tecnico nel match articolo-per-articolo. Fail-close: equivale a contraddizione (block). Mai fail-open.
JudgeLLMUnavailableProvider del Giudice down. Proposte proattive accumulate fino a recovery o timeout 30 min. Reattive passano (la Guardia è sufficiente).
JudgeOutputMalformedJSON non valido dopo 2 retry. Proposta rejected con reason="judge_malformed". Non block: non è colpa della proposta.
SeparationBreachTentativo di passare al Giudice dati oltre l'artefatto (trace, ragionamento). Hard failure in test, warning in produzione.

10. Alternative considerate

AlternativaStatoMotivo
Stesso LLM proposer + self-critique nel prompt scartato Self-enhancement bias documentato. Il proposer valuta sé stesso in modo conforme. Soluzione più economica ma inefficace.
Panel di N LLM che votano rimandato Robusto ma costoso (N chiamate). Da valutare in fase 5-6 se il Giudice singolo mostra varianza eccessiva.
Giudice deterministico a regole scartato I telos sono frasi ambigue per costruzione ("liberare il mio tempo"). Un motore a regole non può stimare il fit. LLM necessario.
Guardia con LLM scartato Vulnerabile a prompt injection. Le Leggi devono essere invariabili al fraseggio. Deterministica sempre.
Un unico scalare Costituzione+Telos scartato Implica che la Costituzione giudichi. Ma la Costituzione non giudica: verifica o blocca. Scale incompatibili, non si sommano.

11. Test di conformità

CasoVerifica
Proposta che viola Legge 0VaglioResult.final_decision = "block". Giudice non invocato (audit verifica assenza di chiamata LLM judge).
Proposta che allinea i telos > θfinal_decision = "publish", per_telos non vuoto.
Proposta che allinea i telos < θfinal_decision = "reject", record in telos_rejected.jsonl.
Richiesta reattiva legittimafinal_decision = "allow". Judge == None. Audit conferma Giudice non chiamato.
Richiesta reattiva che contraddice Legge 1final_decision = "block", anche se l'utente l'ha chiesta esplicitamente.
Tentativo di leak (trace passata al Giudice)SeparationBreach in test. In prod, warning + strip automatico.
Proposta identica valutata due volte di filaRisultati entro varianza LLM attesa (diff < 10% su expected_alignment). Se no, investigate.
Configurazione LLM cambia a runtimeaudit_signature() cambia. I record successivi hanno la nuova firma. Niente retroattivo.

12. Provenienza e riferimenti

Traccia del processo decisionale. Il componente Vaglio è emerso il 22 aprile 2026 in coda al design dei telos, da un'osservazione precisa di Roberto:
"Anche se non intelligente, un LLM tende a valutare i propri risultati in modo conforme: se è arrivato a un determinato output inevitabilmente tenderà a valutarlo positivamente. Serve un punto di vista e di valutazione separato, per quanto possibile, da quello di chi ha proposto o agito una azione. Una sorta di super-io che ha come asse sia la costituzione che le teleologie e che valuti in negativo lo scostamento dalla costituzione e in positivo l'allineamento con le teleologie, con una chiara definizione di un limite invalicabile: la costituzione in caso di contraddizione ha la prevalenza sulla teleologia. Parlo di contraddizione e non di discrepanza o di divergenza, perché queste ultime due sono inevitabili."
Un secondo passaggio ha affinato il principio centrale:
"La Costituzione non giudica, la teleologia sì."
Da questa frase discende la struttura: due fasi di natura opposta, non un'unica funzione di valutazione composita. La Guardia verifica (binario); il Giudice misura (gradiente).

La scelta del nome Vaglio è del 22 aprile 2026: sportivo ("arbitro") e antropomorfico ("giudice", "super-io") sono stati esplicitamente scartati per preservare il design da complessità inutile.

Riferimenti interni

Riferimenti letterari


Continua a leggere

microprogettazione
telos
L'asse positivo del Vaglio. Il Giudice stima fit contro questi fini.
microprogettazione
constitution
Le 4 Leggi. La Guardia del Vaglio ne verifica la contraddizione.
riflessione · 25 min
Dialogo sui fini e i limiti
Il dialogo da cui Vaglio, Telos e la distinzione guardia/giudice sono emersi.
microprogettazione
← Indice componenti
Tutti i doc di Livello 2.

myclaw — vaglio v1.0 — 22 aprile 2026
La Costituzione non giudica, la teleologia sì.