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.
Zuerst lesen: /docs/HOUSEHOLD-CONTEXT/ /trust/ /docs/CORE/
Schritte
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.
deriveConstraintsEach withheld facet carries its rule: never_travels, no_consent, never_travels, unknown_facet. An unknown id is withheld, not passed through.
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.jsonAufgezeichnete 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