Ephemeris4 MIN READ14 / 31

Provenance Store — High-Level Design

Scope decision: This standalone component is dropped from the binder package plan. The design below is historical context. Consumer applications own this responsibility; see the current package architecture.

Status: Draft for review · Part of: Astro Binder · Updated: 2026-10-24

Each response yields one immutable audit record: the provider, engine version, ephemeris files, flags and precision behind its values. No request body is stored.

1. Purpose

Swiss Ephemeris is the source of record, so reproducing a result needs the engine version, file set, time scales and precision, not just birth data. Provenance makes determinism checkable and drift explainable:

  • audit — who asked, which provider answered, under which engine and files;
  • reproducibility — re-run against the recorded engine inputs;
  • operations — cache hits, degradation, latency, no payload logs;
  • privacy — no coordinates or request bodies.

2. Where it sits

calculation facade ──▶ provenance emitter ──▶ async writer ──▶ provenance store
                                                                   │
                                              drift validator ◀────┤
                                              audit queries   ◀────┘
  • Upstream: the calculation facade, after assembly.
  • Downstream: the drift validator reads samples; support looks up one request id.
  • Never: on the request path, a source of response fields, or a store for request payloads.

3. Responsibilities

Component Owns Notes
Record model One immutable record per response Request id, caller, provider, engine and file versions, flags, JD UT/TT, ΔT, precision, cache status, degradation reason, latency
Emitter Turns response context into a record Strips coordinates and request bodies; never retries
Async writer Bounded queue and append Drops and counts under pressure, never blocks
Store Append-only persistence Indexed by request id and engine version
Reader surface Sampled metadata and request-id lookup No coordinate or payload access

4. Architecture

Provenance Store — High-Level Design Reference design. The calculation facade emits one provenance record per response. An emitter strips coordinates and request bodies, a bounded asynchronous writer appends the record to a managed provenance store, and readers use sampled metadata for drift validation or look up a request id for reproducibility. A failed write is counted and never affects the response. Provenance Store — High-Level Design One audit record per response, written after the answer leaves; it never blocks or fails a calculation. Astro Binder service · one deployable Calculation facade assembles the response emits one audit record Provenance emitter request id · caller engine · files · flags Async writer bounded queue drops + counts record async Failed writes are counted, not retried into the request. Records are append-only; coordinates and bodies are never stored. managed data service · off the request path Provenance store one record per response request id · engine version append Readers · outside the request path Drift validator sampled metadata aggregated, no coordinates Audit + reproducibility request id lookups engine-version forensics sampled metadata audit lookups dependency after-response work module entry / saved state boundary

Diagram: reference design, not deployed behaviour.

The store is a managed data service, not in-request compute. Emitter and writer sit in the service for response context; everything after the append is outside it.

5. Rules

  1. One record per response. Cache hits, fresh calculations and degraded answers each produce one record, so counts match responses.
  2. Off the response path. Emission follows assembly; a slow or failed write never changes the answer or its status code.
  3. Loss is visible. Queue overflow and write failures are counted and alerted, never retried synchronously.
  4. No personal payloads. No coordinates, request bodies or provider payloads; time fields are the engine inputs.
  5. Append-only. A record is never updated; a re-emission is a new record, idempotent on the request id.
  6. Engine identity is mandatory. Engine version, ephemeris data set and file-set hash are required, or reproducibility fails.
  7. Cache status is recorded, not inferred. cacheHit, degraded and precision come from the returned response.
  8. Retention is explicit. Storage lifetime is configured and documented; expiry is deliberate.

6. Edge cases

Case Behaviour
Queue full Record dropped and counted; response unaffected
Store unavailable Writer fails within budget, increments the failure metric and alerts
Duplicate emission Idempotent on request id
Cache hit cacheHit: true plus the cached provenance
Degraded answer Degradation reason and reduced precision recorded
Drift validation run Written to the drift store, not as user provenance
Engine or file upgrade New records carry new versions; old ones are not rewritten
Record older than retention Removed by policy; gap visible in audit coverage

7. Out of scope

  • Response assembly and provider choice (facade, router).
  • Normalising values or applying the zodiac (normalizer).
  • Drift thresholds, judging and alerting (drift validator).
  • Request logging, analytics and user-profile stores.
  • Storing raw provider payloads.

8. Planned code

Piece Responsibility
provenance/ProvenanceRecord Immutable audit shape and required fields
provenance/ProvenanceEmitter Build a record from response context; strip payloads
provenance/ProvenanceQueue Bounded in-process handoff
provenance/ProvenanceWriter Asynchronous append, idempotency, failure metrics
provenance/ProvenanceQuery Request-id lookup and sampled metadata for drift