Decision Gate Docs

Avaluació de portes determinista, reproduïble amb decisions auditable.

Asset Core docs

Requirement Evaluation Trees (RET)

A Simple Vista

Què: Àlgebra booleana per a portes, amb gestió d’incògnites (lògica de tres estats) Per què: Fer que la lògica de les portes sigui explícita, auditable i determinista - sense regles ocultes Qui: Desenvolupadors i operadors que redacten requisits complexos de portes Requisits previs: Comprensió bàsica de les condicions (vegeu condition_authoring.md)


Per què RET?

Problema: Com es poden combinar múltiples verificacions d’evidència en una única decisió de porta?

Escenari d’exemple: “Vull desplegar a producció si:

  • L’entorn és ‘producció’ I
  • Les proves han passat I
  • La cobertura és superior al 85% I
  • Almenys 2 de 3 revisors han aprovat

Sense RET: Hauries d’escriure codi personalitzat per a cada Decision Gate, que és:

  • No auditable (la lògica està oculta en el codi)
  • No determinista (el codi pot canviar entre execucions)
  • Difícil de verificar fora de línia (no es pot reproduir sense tornar a executar el codi)

Amb RET: Expreseu la lògica com una estructura d’arbre:

{
  "requirement": {
    "And": [
      { "Condition": "env_is_prod" },
      { "Condition": "tests_ok" },
      { "Condition": "coverage_ok" },
      {
        "RequireGroup": {
          "min": 2,
          "reqs": [
            { "Condition": "alice_approved" },
            { "Condition": "bob_approved" },
            { "Condition": "carol_approved" }
          ]
        }
      }
    ]
  }
}

Beneficis:

  • Explícit: La lògica és visible en l’especificació de l’escenari
  • Auditable: Cada avaluació es rastreja en el runpack
  • Determinista: Mateixa evidència -> mateix resultat
  • Repetible: Pot verificar-se offline sense tornar a consultar els proveïdors

[Seguretat]: La lògica de porta explícita impedeix portes posteriors ocultes. Tota la lògica es declara en l’especificació de l’escenari i es rastreja en el paquet d’execució per a auditoria.


Model Mental: Arbre d’Avaluació RET

Aquí teniu com es valora un arbre de requisits:

RET EVALUATION TREE (simplified)

Gate Requirement (tree structure)
  And
  |-- Pred(A) -> true
  |-- Pred(B) -> unknown
  |-- Not(C) -> false
  `-- RequireGroup (min: 2)
      |-- Pred(D) -> true
      |-- Pred(E) -> true
      `-- Pred(F) -> false

Strong Kleene Logic: And(true, unknown, true, true) -> unknown
(gate holds)

Ordre d’avaluació:

  1. Les condicions de fulla s’avaluen en un estat de tres valors (veritable/fals/desconegut)
  2. Els nodes operadors combinen resultats fills mitjançant lògica de tres estats
  3. L’outcome del node arrel determina el resultat de la porta

Tri-State Outcomes

RET utilitza lògica de tres estats (no només veritable/fals):

  • true: Passis d’accés (tots els requisits satisfets)
  • false: La porta falla (requisits contradits)
  • unknown: Retencions de porta (requisits inconclusos)

Per què tri-estat? Les portes fallan tancades: una porta només es permet passar quan el requisit s’avalua com a true. Els resultats unknown impedeixen que les portes passin fins que l’evidència estigui completa.

Exemple:

Gate: And(tests_ok, coverage_ok)
Conditions:
- tests_ok: true (tests passed)
- coverage_ok: unknown (coverage report missing)

Outcome: unknown (gate holds until coverage is available)

Operadors Bàsics

I

Semàntica: Tots els nens han de ser true

Truth table (2 operands):

LeftRightResult
truetruetrue
truefalsefalse
trueunknownunknown
false(any)false
unknowntrueunknown
desconegutdesconegutdesconegut

Exemple:

{
  "requirement": {
    "And": [
      { "Condition": "tests_ok" },
      { "Condition": "coverage_ok" }
    ]
  }
}

Cas d’ús: Tant les proves com la cobertura han de passar

Comportament:

  • Tot true -> true (passis de porta)
  • Any false -> false (la porta falla)
  • Altrament -> unknown (la porta es manté)

O bé

Semàntica: Qualsevol fill pot ser true

Truth table (2 operands):

LeftRightResult
true(any)true
falsefalsefalse
falseunknownunknown
unknownfalseunknown
desconegutdesconegutdesconegut

Exemple:

{
  "requirement": {
    "Or": [
      { "Condition": "manual_override" },
      { "Condition": "tests_ok" }
    ]
  }
}

Cas d’ús: O bé sobreescriptura manual O bé proves automatitzades han de passar

Comportament:

  • Any true -> true (passos de porta)
  • Tot false -> false (la porta falla)
  • Altrament -> unknown (la porta es manté)

No

Semàntica: Invertir l’outcome del fill

Truth table:

InputResult
truefalse
falsetrue
Taula de veritat:Entrada

Exemple:

{
  "requirement": {
    "And": [
      { "Condition": "tests_ok" },
      { "Not": { "Condition": "blocklist_hit" } }
    ]
  }
}

Cas d’ús: Les proves han de passar I la llista negra NO ha de ser activada

Comportament:

  • true -> false
  • fals -> cert
  • unknown -> desconegut (fail-closed: no es pot confirmar l’absència)

RequireGroup (Quorum)

Semàntica: Almenys N de M nens han de ser true

Paràmetres:

  • min: Nombre mínim de resultats true requerits
  • reqs: Array de requisits fills

Exemple:

{
  "requirement": {
    "RequireGroup": {
      "min": 2,
      "reqs": [
        { "Condition": "alice_approved" },
        { "Condition": "bob_approved" },
        { "Condition": "carol_approved" }
      ]
    }
  }
}

Cas d’ús: Almenys 2 de 3 revisors han d’aprovar

Comportament:

  • Comptar resultats true
  • Si el compte >= min -> true (quorum assolit)
  • Si count + unknowns < min -> false (quòrum impossible)
  • Altrament -> unknown (quorum pendent)

Truth table examples:

OutcomesminResultReason
[true, true, false]2true2 true >= min (quorum reached)
[true, unknown, unknown]2unknown1 true, can’t reach min yet
[true, false, false]2false1 true, max possible is 1 < min
[true, true, unknown]2true2 true >= min (already met)
[fals, fals, fals]2fals0 vertader, impossible

[Desenvolupador]: Vegeu ret-logic crate per a la implementació. RequireGroup compta veritable/fals de manera independent (desconegut no és ni veritable ni fals).


Condició (Fulla)

Semàntica: Referència a una condició per clau

Exemple:

{
  "requirement": { "Condition": "tests_ok" }
}

Cas d’ús: Porteria simple amb una única condició

Comportament:

  • Avalua el resultat tri-estat de la condició
  • La condició ha d’existir a ScenarioSpec.conditions

Regles de Propagació Tri-Estat

Com es propaguen els resultats unknown a través dels operadors:

I Propagació

OperandsResultReason
And(true, true, true)trueTots els requisits satisfets
And(true, false, true)falseUn falla -> And falla
And(true, unknown, true)unknownNo es pot confirmar que tots siguin true encara
And(false, unknown)falseUn falla (curtcircuit)
And(unknown, unknown)unknownEvidència pendent

Regla: false domina; tot true dóna true; altrament unknown


O Propagació

OperandsResultatRaó
Or(false, false, false)falseTots els requisits han fallat
Or(true, false, false)trueUn té èxit -> Or té èxit
Or(false, unknown, false)unknownNo es pot confirmar que tots siguin falsos encara
Or(true, unknown)trueUn té èxit (curtcircuit)
Or(unknown, unknown)unknownEvidència pendent

Regla: true domina; tot false dóna false; altrament unknown


RequireGroup Propagation

Resultatsmincomptatge veritablecomptatge desconegutResultat
[T, T, F]220veritable (min assolit)
[T, U, U]212desconegut (max 3, necessiten 2)
[T, F, F]210fals (max 1 < min)
[U, U, U]203desconegut (max 3, necessiten 2)
[F, F, F]200fals (impossible)

Regla:

  • Si true_count >= min -> true (quòrum assolit)
  • Si true_count + unknown_count < min -> false (quòrum impossible)
  • Altrament -> unknown (quorum pendent)

[LLM Agent]: Quan RequireGroup retorna unknown, necessites més proves. Comprova quines condicions són desconegudes i treballa per satisfer-les.


Casos d’ús pràctics

Simple Gate: Ambdues Condicions

Escenari: Desplegar si les proves han passat I la cobertura és superior al 85%

{
  "gate_id": "quality_gate",
  "requirement": {
    "And": [
      { "Condition": "tests_ok" },
      { "Condition": "coverage_ok" }
    ]
  }
}

Quorum Gate: 2 de 3 Revisors

Escenari: Fusionar PR si almenys 2 de 3 revisors han aprovat

{
  "gate_id": "review_gate",
  "requirement": {
    "RequireGroup": {
      "min": 2,
      "reqs": [
        { "Condition": "alice_approved" },
        { "Condition": "bob_approved" },
        { "Condition": "carol_approved" }
      ]
    }
  }
}

Exclusió Porta: NO a la llista negra

Escenari: Desplegar si NO està a la llista negra

{
  "gate_id": "blocklist_gate",
  "requirement": {
    "Not": { "Condition": "blocklist_hit" }
  }
}

Complex Gate: (A I B) O C

Escenari: Desplegar si (les proves han passat I la cobertura és correcta) O sobreescriptura manual

{
  "gate_id": "deploy_gate",
  "requirement": {
    "Or": [
      {
        "And": [
          { "Condition": "tests_ok" },
          { "Condition": "coverage_ok" }
        ]
      },
      { "Condition": "manual_override" }
    ]
  }
}

Ramificació en Resultats de Portes

Podeu dirigir-vos a diferents etapes en funció dels resultats de les portes utilitzant advance_to.branch:

{
  "advance_to": {
    "kind": "branch",
    "branches": [
      { "gate_id": "env_gate", "outcome": "true", "next_stage_id": "ship" },
      { "gate_id": "env_gate", "outcome": "unknown", "next_stage_id": "hold" },
      { "gate_id": "env_gate", "outcome": "false", "next_stage_id": "deny" }
    ],
    "default": null
  }
}

Com funciona:

  1. Avaluar el gate env_gate
  2. Comprovar el resultat contra les branques (de dalt a baix)
  3. La primera branca coincident guanya
  4. Si no hi ha coincidència i default és nul -> error

Casos d’ús:

  • Cert: Avançar al desplegament en producció
  • Desconegut: Esperar revisió manual
  • Fals: Rebutjar i notificar

[Seguretat]: Utilitzeu ramificacions per implementar alternatives de seguretat. Per exemple, rutegeu unknown a revisió manual en comptes d’avançar automàticament.


Logic Mode: Strong Kleene

Decision Gate utilitza lògica Kleene forta (tres estats):

Propertats clau:

  • And(true, unknown) -> unknown (no es pot confirmar que tot sigui cert)
  • Or(false, unknown) -> unknown (no es pot confirmar que tot sigui fals)
  • Not(unknown) -> unknown (no es pot invertir la incertesa)

Alternativa (no utilitzada): Lògica de Bochvar (qualsevol desconegut -> desconegut)

Per què Kleene?

  • Més intuïtiu per a proves parcials
  • Curt-circuits quan sigui possible (And(false, unknown) -> false)
  • Els equilibris fallen tancats amb usabilitat

[Desenvolupador]: Vegeu crates/ret-logic/src/lib.rs per a l’algorisme d’avaluació.


Casos d’ús

Primari: Portes complexes que requereixen combinacions booleanes (I, O, quòrum) Secundari: Portes simples amb condicions úniques (només node de condició) Antipatró: No anideu RETs massa profundament - preferiu condicions enfocades i arbres plans


Solució de problemes

Problema: Porta enganxada en unknown

Síntomes: La porta mai passa, sempre retorna unknown

Causa: Una o més condicions s’estan avaluant com a unknown

Solució:

  1. Comproveu el rastre de la porta per veure quines condicions són unknown
  2. Solucioneu els problemes de condicions subjacents (vegeu condition_authoring.md)
  3. Common causes:
    • Error del proveïdor (per exemple, fitxer absent per al proveïdor json)
    • JSONPath no trobat (desajustament de l’eina)
    • Incompatibilitat de tipus per a un comparador sensible al tipus

Problema: RequireGroup Mai Passa

Síntomes: RequireGroup sempre retorna false o unknown

Causa: min és massa alt, o massa condicions estan fallant

Solució:

  1. Comprovar el valor min en comparació amb el nombre de condicions
  2. Verifiqueu els resultats de condició en el rastre de la porta
  3. Assegureu-vos que almenys min condicions poden ser true simultàniament

Exemple:

// BAD: min is 3, but only 2 conditions
{
  "RequireGroup": {
    "min": 3,
    "reqs": [
      { "Condition": "a" },
      { "Condition": "b" }
    ]
  }
}

// GOOD: min <= number of conditions
{
  "RequireGroup": {
    "min": 2,
    "reqs": [
      { "Condition": "a" },
      { "Condition": "b" },
      { "Condition": "c" }
    ]
  }
}

Problema: La branca no coincideix

Síntomes: Error d’evaluació de la porta: “No hi ha cap branca coincident”

Causa: El resultat de la porta no coincideix amb cap branca, i default és nul

Solució:

  1. Afegiu branques per a tots els possibles resultats (veritable/fals/desconegut)
  2. OR estableix default a una etapa de reserva
  3. Exemple:
{
  "branches": [
    { "gate_id": "gate1", "outcome": "true", "next_stage_id": "ship" },
    { "gate_id": "gate1", "outcome": "false", "next_stage_id": "deny" }
  ],
  "default": "hold"  // Fallback for unknown
}

Consells d’autoria

1. Mantingueu les claus de condició estables i descriptives

  • Utilitzeu tests_ok no pred1
  • Les claus es referencien en runpacks per a auditoria

2. Utilitzeu RequireGroup per a comprovacions de tipus quorum

  • Exemple: “2 de 3 revisors”, “3 de 5 comprovacions de datacenter”
  • Alternativa: Múltiples condicions And (però menys flexibles)

3. Preferir arbres més petits amb condicions enfocades

  • Més fàcil d’auditar i entendre
  • Més fàcil de depurar quan fallen les portes

4. Validar l’estructura RET durant la definició de l’escenari

  • La Decision Gate valida els RETs en el moment de scenario_define
  • Fallida ràpida si l’estructura és invàlida (per exemple, referenciant condicions inexistents)

5. Utilitzeu ramificacions per a solucions de seguretat en cas de fallada

  • Rutar unknown a revisió manual
  • Ruta false per alertar/denegar
  • Route true per avançar

Camins d’Aprenentatge de Referència Creuada

Camí de Nou Usuari: getting_started.md -> condition_authoring.md -> AQUESTA GUIA -> integration_patterns.md

Camí de Lògica Avançada: AQUESTA GUIA -> evidence_flow_and_execution_model.md -> Entendre com s’integren els RETs en el pipeline d’avaluació

Camí de Seguretat: AQUESTA GUIA -> security_guide.md -> Apreneu com la lògica explícita evita portes enrere


Glossari

I: Operador que requereix que tots els nens siguin true.

Porta: Punt de decisió en un escenari, avaluat mitjançant RET contra proves.

O: Operador que requereix que qualsevol fill sigui true.

Nota: Operador que inverteix el resultat del fill (true <-> false).

Condició: Definició de comprovació d’evidències: consulta + comparador + valor esperat.

RequireGroup: Operador de quòrum que requereix almenys N de M fills per ser true.

RET: Arbre d’Avaluació de Requisits, àlgebra booleana (I/O/No/RequerirGrup) per a portes.

TriState: Resultat de l’avaluació: true (aprovat), false (suspendre) o unknown (en espera).

Lògica Kleene Forta: Mode de lògica de tres estats on And(true, unknown) -> unknown.