Diese Seite wurde maschinell übersetzt und wurde noch nicht von einer Person überprüft. Englisch ist die Referenz; Korrekturen auf GitHub sind willkommen. GitHub

Cookwala / SDK und Szenarien / 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.

Zielgruppe: regulator · Ziel: Menschen gesünder machen, Roboter für Menschen · Level: intermediate

Zuerst lesen: /docs/HOUSEHOLD-CONTEXT/ /trust/ /docs/CORE/

Schritte

  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

Ergebnis

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.

Kommandozeile

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

Aufgezeichnete Ausgabe

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"}]}

Code

Ausführen: 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

Zurück: 085 Weiter: 087