build(agent): molt-z#db0ec5 iteration

This commit is contained in:
agent-db0ec53c058f1326 2026-04-15 21:29:22 +02:00
parent a2787cbe34
commit 27df9bd8a2
6 changed files with 158 additions and 1 deletions

View File

@ -1,9 +1,11 @@
# OpenBench: Privacy-Preserving Benchmarking (MVP)
This repository contains a minimal, working MVP of the OpenBench platform focused on:
- This repository contains a minimal, working MVP of the OpenBench platform focused on:
- An offline-first KPI data model (Revenue, COGS, inventory turns, lead time, CAC, LTV).
- A simple, privacy-preserving aggregation primitive (Laplace-noise-enabled) for anonymized benchmarking.
- A lightweight Python packaging setup compatible with pytest-based tests and python -m build packaging checks.
- A minimal data-contract system (DataContract) and an in-memory contract registry for versioned payload schemas.
- A pluggable adapter framework with sample POSAdapter and ERPAdapter to bootstrap data ingestion.
How to run
- Install dependencies and run tests: `bash test.sh`

View File

@ -5,6 +5,20 @@ performing privacy-preserving aggregations, and computing simple derived metrics
"""
from .core import KPIRecord, LocalStore, SecureAggregator, GrowthCalculator
from .contracts import DataContract, ContractRegistry
from .adapters.pos import POSAdapter
from .adapters.erp import ERPAdapter
__all__ = [
"KPIRecord",
"LocalStore",
"SecureAggregator",
"GrowthCalculator",
"DataContract",
"ContractRegistry",
"POSAdapter",
"ERPAdapter",
]
__all__ = [
"KPIRecord",

View File

@ -0,0 +1,16 @@
from __future__ import annotations
from typing import List
from openbench_privacy_preserving_benchmarkin.core import KPIRecord
from openbench_privacy_preserving_benchmarkin.contracts import DataContract
class Adapter:
"""Base adapter interface for data sources."""
def __init__(self, name: str, contract: DataContract):
self.name = name
self.contract = contract
def collect(self) -> List[KPIRecord]: # pragma: no cover - abstract in base
raise NotImplementedError

View File

@ -0,0 +1,29 @@
from __future__ import annotations
from typing import List
from .base import Adapter
from openbench_privacy_preserving_benchmarkin.core import KPIRecord
from openbench_privacy_preserving_benchmarkin.contracts import DataContract
class ERPAdapter(Adapter):
"""A toy ERP adapter that yields KPIRecords."""
def __init__(self, name: str, contract: DataContract):
super().__init__(name, contract)
def collect(self) -> List[KPIRecord]:
k1 = KPIRecord(
revenue=800.0,
cogs=500.0,
inventory_turns=1.8,
lead_time=4.0,
cac=40.0,
ltv=900.0,
region="default",
industry="Manufacturing",
anon_id=f"{self.name}-erp1",
timestamp="2020-01-03T00:00:00Z",
)
return [k1]

View File

@ -0,0 +1,44 @@
from __future__ import annotations
from typing import List
from .base import Adapter
from openbench_privacy_preserving_benchmarkin.core import KPIRecord
from openbench_privacy_preserving_benchmarkin.contracts import DataContract
class POSAdapter(Adapter):
"""A toy POS (Point-of-Sale) adapter that yields KPIRecords."""
def __init__(self, name: str, contract: DataContract, seed: int = 42):
super().__init__(name, contract)
self._seed = seed
def collect(self) -> List[KPIRecord]:
# For MVP: generate two deterministic KPI records as samples
# In a real implementation this would pull from a POS feed.
k1 = KPIRecord(
revenue=1000.0,
cogs=600.0,
inventory_turns=2.5,
lead_time=2.0,
cac=50.0,
ltv=1200.0,
region="default",
industry="Retail",
anon_id=f"{self.name}-sample1",
timestamp="2020-01-01T00:00:00Z",
)
k2 = KPIRecord(
revenue=1500.0,
cogs=900.0,
inventory_turns=3.0,
lead_time=3.0,
cac=60.0,
ltv=1700.0,
region="default",
industry="Retail",
anon_id=f"{self.name}-sample2",
timestamp="2020-01-02T00:00:00Z",
)
return [k1, k2]

View File

@ -0,0 +1,52 @@
from __future__ import annotations
import uuid
from dataclasses import dataclass, asdict
from typing import Dict, Any
from .core import KPIRecord
@dataclass
class DataContract:
"""A minimal, versioned data contract for KPI payloads.
This is intentionally lightweight for MVP purposes. Each contract
defines a unique id, a version, a JSON schema-like payload description,
and privacy controls flags used by aggregators.
"""
contract_id: str
version: int
schema: Dict[str, Any]
privacy_flags: Dict[str, Any]
description: str = ""
def to_dict(self) -> Dict[str, Any]:
return asdict(self)
@staticmethod
def make_new(schema: Dict[str, Any], privacy_flags: Dict[str, Any], description: str = "") -> DataContract:
return DataContract(
contract_id=uuid.uuid4().hex,
version=1,
schema=schema,
privacy_flags=privacy_flags,
description=description,
)
class ContractRegistry:
"""In-memory registry for data contracts."""
def __init__(self) -> None:
self._contracts: Dict[str, DataContract] = {}
def register(self, contract: DataContract) -> None:
self._contracts[contract.contract_id] = contract
def get(self, contract_id: str) -> DataContract | None:
return self._contracts.get(contract_id)
def all(self) -> Dict[str, DataContract]:
return dict(self._contracts)