Federated Safety Signal Sharing¶
FederatedSafetySignalAggregator turns tenant-safe
DirectorSafetySignal envelopes into anonymous, differentially private
aggregate guard telemetry for cross-organisation sharing.
It enforces four boundaries before release:
- input must validate as a
DirectorSafetySignal; - each signal must carry a tenant id for contribution bounding;
- each tenant can contribute at most one count per category per release window;
- releases require at least
min_tenantsdistinct tenants and omit raw counts by default.
from director_ai.core import (
FederatedSafetySignalAggregator,
PrivacyAccountant,
director_safety_signal_from_event,
)
from director_ai.core.safety_event import SafetyEvent
accountant = PrivacyAccountant(max_epsilon=5.0)
aggregator = FederatedSafetySignalAggregator(
epsilon=0.9,
accountant=accountant,
min_tenants=2,
)
event = SafetyEvent.from_policy_decision(
hook_id="stream",
hook_scope="streaming",
policy_decision="halt",
halt_reason="coherence",
tenant_safe_explanation="Tenant-safe halt summary.",
tenant_id="tenant-a",
)
signal = director_safety_signal_from_event(
event,
producer_id="runtime-a",
framework="generic",
)
aggregator.submit_signal(signal)
release() returns noised counts and privacy metadata:
payload contains noisy_counts, epsilon_spent, category names, cohort
counts, and a privacy block with payload_classification set to
anonymous_dp_aggregate. It does not include tenant ids, raw prompts, raw
completions, credentials, media, sensor payloads, or raw aggregate counts.
Raw aggregate counts can be included only for local audit/debug use:
Do not publish include_raw=True payloads across tenant or organisation
boundaries.
director_ai.core.federated_privacy.signal_sharing.FederatedSafetySignalAggregator
¶
FederatedSafetySignalAggregator(*, epsilon: float, categories: Sequence[str] = DEFAULT_SIGNAL_CATEGORIES, accountant: PrivacyAccountant | None = None, min_tenants: int = 2, seed: int | None = None, allow_insecure_seed: bool = False)
Aggregate tenant-safe guard signals for federated sharing.
The aggregator accepts only validated :class:DirectorSafetySignal
envelopes. Each tenant can contribute at most one count to each category
within a release window, bounding per-category tenant sensitivity at one.
Releases are Laplace-noised through :class:FederatedHistogram and blocked
until a minimum distinct-tenant cohort is present.
director_ai.core.federated_privacy.signal_sharing.FederatedSafetySignalRelease
dataclass
¶
FederatedSafetySignalRelease(noisy_counts: Mapping[str, float], epsilon_spent: float, categories: tuple[str, ...], signal_count: int, distinct_tenants: int, privacy_unit: str = 'tenant', mechanism: str = 'laplace', raw_counts: Mapping[str, int] = dict())
One anonymous differentially private safety-signal aggregate.
to_dict
¶
Return a transport-safe release payload.
Raw aggregate counts are omitted by default. They are useful for local audits and tests, but cross-organisation sharing should use the noised values plus the attached privacy metadata.