Skip to content

feat: swift declaration package (EffacedKit) — author PII in swift, run the python engine #73

Description

@jaylann

A SwiftPM package that lets developers declare their PII in Swift the way they do in Python — working on both server-side Swift (Vapor/Hummingbird, owns a Postgres DB) and Apple platforms (iOS/macOS apps) — without forking the GDPR engine into Swift.

Decided architecture (ideation): Swift DSL → manifest → one Python engine

Swift app / Vapor server  →  declares PII in Swift types
        ▼
 effaced manifest (versioned JSON)   ← language-neutral contract (#63)
        ▼
 Python engine executes
   • server: co-located service (sidecar) or, later, embedded via PythonKit
   • iOS/macOS: calls the service over HTTP

Why not a native Swift engine port: under widened SemVer what gets deleted is the API; two engines that must delete identically forever is the worst maintenance risk. The manifest is already versioned + forward-migrated, so Swift only authors it.

Why "Both" splits in two: effaced erases transactionally against a DB the app owns (ADR 0006/0007). An iOS app owns no such DB, and embedding CPython on-device is heavy and pointless. So Apple = thin client; server = executes. One shared Swift declaration layer, two execution backends.

Layers (split into child issues if needed)

  1. Declaration DSL — Swift value types mirroring the manifest (DataMap/TableEntry/ColumnEntry/PiiSpec/SubjectLink + PiiCategory/LegalBasis/ErasureStrategy); @resultBuilder so it feels like the Python annotation experience.
  2. Manifest encoderCodable lowering to the exact DataMap.to_payload() JSON (schema_version: 1).
  3. GDPRClient — thin async URLSession client hitting the service endpoints (export/erase/consent + manifest register). All an Apple app needs.
  4. (Later, optional) in-process runner — PythonKit embedding effaced for single-binary server deploys. Deferred; the sidecar gives identical behaviour without CPython-bundling pain.

Key correctness mechanism — cross-language golden test

Swift-emitted manifest JSON must round-trip through Python DataMap.from_payload(...).to_payload() byte-equivalently (and vice-versa). A shared fixtures/manifest_v1.json checked by both a Swift test and a Python test keeps the schemas in lockstep forever.

Placement & CI

Outside the uv workspace, mirroring site/ (ADR 0011). Needs a Swift CI job (swift-actions/setup-swift, or the netcup ARM64 self-hosted runner).

Related: #63.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:manifestDataMap, schema versioning, migrationarea:swiftSwift declaration package (EffacedKit)status:exploringDemand-pulled idea — scope notes, no commitmenttype:featNew capability

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions