85 lines
2.8 KiB
Python
85 lines
2.8 KiB
Python
from __future__ import annotations
|
|
"""Tiny DSL-like helpers for HopeMesh primitives and contract tooling."""
|
|
|
|
from typing import Iterable
|
|
|
|
from .core import LocalProblem, SharedVariables, PlanDelta, Policy, AttestationHint, AuditLog, PrivacyBudget
|
|
from .contracts import validate_plan_deltas
|
|
|
|
def make_local_problem(
|
|
name: str,
|
|
region: str | None = None,
|
|
objective: str = "",
|
|
constraints: dict | None = None,
|
|
**metadata,
|
|
) -> LocalProblem:
|
|
return LocalProblem(name=name, region=region, objective=objective, constraints=constraints or {}, metadata=metadata)
|
|
|
|
def make_shared_variables(
|
|
description: str = "",
|
|
data: dict | None = None,
|
|
aggregate_type: str = "sum",
|
|
privacy_budget_tag: str | None = None,
|
|
source_regions: list[str] | None = None,
|
|
) -> SharedVariables:
|
|
return SharedVariables(
|
|
description=description,
|
|
data=data or {},
|
|
aggregate_type=aggregate_type,
|
|
privacy_budget_tag=privacy_budget_tag,
|
|
source_regions=source_regions or [],
|
|
)
|
|
|
|
def make_plan_delta(
|
|
delta_id: str,
|
|
actions: list[dict],
|
|
actor_did: str | None = None,
|
|
causality: dict | None = None,
|
|
policy_tags: list[str] | None = None,
|
|
privacy_budget_tag: str | None = None,
|
|
signature: str | None = None,
|
|
**annotations,
|
|
) -> PlanDelta:
|
|
return PlanDelta(
|
|
delta_id=delta_id,
|
|
actions=actions,
|
|
actor_did=actor_did,
|
|
causality=causality or {},
|
|
policy_tags=policy_tags or [],
|
|
privacy_budget_tag=privacy_budget_tag,
|
|
signature=signature,
|
|
annotations=annotations,
|
|
)
|
|
|
|
def make_policy(policy_id: str, **rules) -> Policy:
|
|
return Policy(policy_id=policy_id, rules=rules)
|
|
|
|
def make_attestation_hint(hint_id: str, scheme: str = "dummy", payload: dict | None = None) -> AttestationHint:
|
|
return AttestationHint(hint_id=hint_id, scheme=scheme, payload=payload or {})
|
|
|
|
def make_audit_log(entry_id: str, message: str, signature: str | None = None) -> AuditLog:
|
|
return AuditLog(entry_id=entry_id, message=message, signature=signature)
|
|
|
|
def make_privacy_budget(budget_id: str, limit: float) -> PrivacyBudget:
|
|
return PrivacyBudget(budget_id=budget_id, limit=limit)
|
|
|
|
|
|
def merge_plan_deltas(deltas: Iterable[PlanDelta]) -> PlanDelta:
|
|
ordered = sorted(deltas, key=lambda delta: (delta.timestamp, delta.delta_id))
|
|
actions: list[dict] = []
|
|
contributors: list[str] = []
|
|
for delta in ordered:
|
|
contributors.append(delta.delta_id)
|
|
actions.extend(delta.actions)
|
|
delta_id = "merged-" + "-".join(contributors) if contributors else "merged-empty"
|
|
return PlanDelta(
|
|
delta_id=delta_id,
|
|
actions=actions,
|
|
causality={"merged_from": len(contributors)},
|
|
annotations={"contributors": contributors},
|
|
)
|
|
|
|
|
|
def validate_deltas(deltas: Iterable[PlanDelta]) -> list[str]:
|
|
return validate_plan_deltas(deltas)
|