Esta página foi traduzida por máquina e ainda não foi revisada por uma pessoa. O inglês é a referência; correções são bem-vindas no GitHub. GitHub

Cookwala / SDK e cenários / 086

Three travel rules: never, derived, consented, and a consent that cannot override never

The facet registry (vocab/facets.json) gives each of its 139 facets a travel rule: 45 never leave the home, 81 leave only as derived constraints, 13 may be disclosed by consent. Hand the derivation one facet of each kind plus an unknown id and read the reasons.

Público: regulator · Objetivo: Torne as pessoas mais saudáveis, Robôs para pessoas · Nível: intermediate

Leia primeiro: /docs/HOUSEHOLD-CONTEXT/ /trust/ /docs/CORE/

Passos

  1. Five facets for a planner: a health condition (never), an allergy (derived), the device identity (consented), the mandate authority (never) and an id that is not in the registry. deriveConstraints

  2. Each withheld facet carries its rule: never_travels, no_consent, never_travels, unknown_facet. An unknown id is withheld, not passed through.

  3. A consent grant that names the health condition for the planner changes nothing: consent cannot move a facet out of never. deriveConstraints

Resultado

You can audit the registry's travel rules yourself and know that a privacy class may be raised, never lowered, and that never is never. Next: 087 validates the household documents.

Linha de comando

jq '[.entries[].travel] | group_by(.) | map({(.[0]): length}) | add' vocab/facets.json
jq '.entries | length' vocab/facets.json

Saída gravada

Status: ok

[1] deriveConstraints: {"constraints": [{"type": "allergen_block", "derivedFrom": ["cw.facet.household.health.allergies"]}], "disclosed": [], "withheld": [{"facet": "cw.facet.household.health.conditions", "reason": "never_travels"}, {"facet": "cw.facet.self.identity", "reason": "no_consent"}, {"facet": "cw.facet.mandate.authority", "reason": "never_travels"}, {"facet": "cw.facet.made.up", "reason": "unknown_facet"}]}
[3] deriveConstraints: {"constraints": [], "disclosed": [], "withheld": [{"facet": "cw.facet.household.health.conditions", "reason": "never_travels"}]}

Código

Executar: python scenarios/out/086-facet-travel-rules-never-derived-consented/python.py

# Scenario 086: Three travel rules: never, derived, consented, and a consent that cannot override never
# The facet registry (vocab/facets.json) gives each of its 139 facets a travel rule: 45 never leave the home, 81 leave only as derived constraints, 13 may be disclosed by consent. Hand the derivation one facet of each kind plus an unknown id and read the reasons.
# Run a hub first: python hub/cookwala_hub.py --recipes examples
import json, os
from cookwala.client import CookwalaClient, CookwalaProblem

def load(path):
    with open(path, encoding="utf-8") as f:
        return json.load(f)

def pick(obj, path):
    for part in path.replace("]", "").replace("[", ".").split("."):
        obj = obj[int(part)] if part.isdigit() else (len(obj) if part == "length" else obj.get(part))
    return obj

c = CookwalaClient(os.environ.get("COOKWALA_HUB", "http://localhost:7878"))


# Step 1: Five facets for a planner: a health condition (never), an allergy (derived), the device identity (consented), the mandate authority (never) and an id that is not in the registry.
travel = c.derive_constraints([{"facet": "cw.facet.household.health.conditions"}, {"facet": "cw.facet.household.health.allergies"}, {"facet": "cw.facet.self.identity"}, {"facet": "cw.facet.mandate.authority"}, {"facet": "cw.facet.made.up"}], "planner")
assert pick(travel, "constraints.length") == 1, pick(travel, "constraints.length")
print("ok", "constraints.length", "=", 1)
assert pick(travel, "constraints[0].type") == "allergen_block", pick(travel, "constraints[0].type")
print("ok", "constraints[0].type", "=", "allergen_block")
assert pick(travel, "disclosed.length") == 0, pick(travel, "disclosed.length")
print("ok", "disclosed.length", "=", 0)
assert pick(travel, "withheld.length") == 4, pick(travel, "withheld.length")
print("ok", "withheld.length", "=", 4)

# Step 2: Each withheld facet carries its rule: never_travels, no_consent, never_travels, unknown_facet. An unknown id is withheld, not passed through.
assert pick(travel, "withheld[0].reason") == "never_travels", pick(travel, "withheld[0].reason")
print("ok", "withheld[0].reason", "=", "never_travels")
assert pick(travel, "withheld[1].reason") == "no_consent", pick(travel, "withheld[1].reason")
print("ok", "withheld[1].reason", "=", "no_consent")
assert pick(travel, "withheld[2].reason") == "never_travels", pick(travel, "withheld[2].reason")
print("ok", "withheld[2].reason", "=", "never_travels")
assert pick(travel, "withheld[3].reason") == "unknown_facet", pick(travel, "withheld[3].reason")
print("ok", "withheld[3].reason", "=", "unknown_facet")

# Step 3: A consent grant that names the health condition for the planner changes nothing: consent cannot move a facet out of never.
override = c.derive_constraints([{"facet": "cw.facet.household.health.conditions"}], "planner", [{"id": "cg-test-1", "grantedBy": "owner", "scope": {"facets": ["cw.facet.household.health.conditions"]}, "recipientRole": "planner", "purpose": "test", "grantedAt": "2026-10-04T12:00:00Z", "withdrawable": True}])
assert pick(override, "disclosed.length") == 0, pick(override, "disclosed.length")
print("ok", "disclosed.length", "=", 0)
assert pick(override, "withheld.length") == 1, pick(override, "withheld.length")
print("ok", "withheld.length", "=", 1)
assert pick(override, "withheld[0].reason") == "never_travels", pick(override, "withheld[0].reason")
print("ok", "withheld[0].reason", "=", "never_travels")

print("scenario complete")

scenarios/086-facet-travel-rules-never-derived-consented.json

Anterior: 085 Próximo: 087