# Decision ledger

Generated from `assets/fixtures-atlas.js`. Status: **EST** established · **PROP** proposed · **OPEN** needs a decision.

The guide annotation at the end of this file gathers storage and authentication alternatives already written in DEC-01, DJ-01, ADR-007, ADR-010, and the trust-boundary recommendation. It does not add a decision and it does not change the rows below.

| ID | Decision | Status |
|---|---|---|
| DEC-01 | Database selection | OPEN |
| DEC-02 | Permitted automatic acceptance | PROP |
| DEC-03 | Parser and profile versioning | PROP |
| DEC-04 | Shipping-policy precedence | PROP |
| DEC-05 | Freshness thresholds | OPEN |
| DEC-06 | Evidence retention | OPEN |
| DEC-07 | Collector geography requirements | PROP |
| DEC-08 | Confirmed budget; proposed launch workload | BUDGET CONFIRMED / WORKLOAD PROPOSED |
| DEC-09 | Event ordering and idempotency | EST |
| DEC-10 | Where shipping evaluation runs | PROP |

## DEC-01 · Database selection — OPEN

- **Recommended default:** Keep managed PostgreSQL (relational + JSONB) reached through Hyperdrive.
- **Rationale:** Baseline design; transactional outbox, JSONB evidence locators and review-case history fit it directly. Hyperdrive is a connection layer to an existing database, not storage.
- **Alternatives:** D1 (SQLite semantics) — Cloudflare-native; requires deliberate schema, query, transaction and capacity validation; Self-hosted PostgreSQL
- **Evidence that would change it:** A D1 spike that reproduces outbox-in-transaction, JSON querying and expected data volume within published limits.
- **Provenance:** PostgreSQL is the baseline (EST); D1 is an alternative under evaluation.

## DEC-02 · Permitted automatic acceptance — PROP

- **Recommended default:** Auto-accept only R-ID-01 (GTIN + normalized MPN + all identity attributes equal) and R-ID-04 guards. Human approval for any LLM-dependent new identity or changed mapping.
- **Rationale:** EST: deterministic validated matches may proceed; LLM-dependent identities and mapping changes need humans initially. Model confidence or two-model agreement is not independent evidence.
- **Alternatives:** Allow R-ID-02 (MPN + capacity, no GTIN) to auto-accept with sampling audit; Auto-accept fully parsed policy revisions
- **Evidence that would change it:** Audit of auto-accepted decisions showing zero false merges across a reviewed sample; reviewer workload data.
- **Provenance:** Human approval rule is EST; the R-ID rule set is PROP.

## DEC-03 · Parser and profile versioning — PROP

- **Recommended default:** Adapters use semver (pa_*@x.y.z); profiles use integer versions (np_*@n). Every claim records method + version; replays pin the new versions and keep original observed_at.
- **Rationale:** Makes improvement replays comparable and lets corrections survive reprocessing.
- **Alternatives:** Content-hash versions; Single global pipeline version
- **Evidence that would change it:** Evidence that adapter churn makes semver bookkeeping costly.
- **Provenance:** Recording versions is EST; scheme is PROP.

## DEC-04 · Shipping-policy precedence — PROP

- **Recommended default:** Most specific scope wins: product/ship-class exclusion > postal area > subdivision > country. At equal specificity, exclusion beats inclusion. Customer conditions grant only when known. Conflicts or unparsed blocking conditions → unknown.
- **Rationale:** Matches EST rule that conflicting or unparsed conditions yield unknown when they block a justified answer.
- **Alternatives:** Latest-captured clause wins; Merchant-wide policy overrides source policy
- **Evidence that would change it:** Real policies where a merchant-wide clause legitimately overrides a source clause.
- **Provenance:** Unknown-on-conflict is EST; ordering is PROP.

## DEC-05 · Freshness thresholds — OPEN

- **Recommended default:** Start with inventory 24 h, price 24 h, shipping policy 7 days, heartbeat lease 90 s; show stale values with their last observation, never as zero.
- **Rationale:** Placeholders chosen to make scenario 7 visible; not derived from measured source behaviour.
- **Alternatives:** Per-source thresholds in the source profile; Per-class thresholds (perishables shorter)
- **Evidence that would change it:** Observed change frequency per source after a month of collection.
- **Provenance:** Stale ≠ zero is EST; thresholds are OPEN.

## DEC-06 · Evidence retention — OPEN

- **Recommended default:** Retain artifacts referenced by accepted facts, decisions, open cases and regression fixtures. Expire unreferenced artifacts after a configurable window (value to be chosen).
- **Rationale:** Corrections and replays need original evidence; unreferenced bulk HTML has storage cost and possible terms-of-use exposure.
- **Alternatives:** Keep everything; Keep extracted claims only
- **Evidence that would change it:** Source terms of use, legal review, and measured artifact volume.
- **Provenance:** Claims must retain capture + locator (EST); retention window OPEN.

## DEC-07 · Collector geography requirements — PROP

- **Recommended default:** Declare egress requirements per source profile. Only collectors with verified outbound geography satisfy them. Never infer storefront market or shipping from execution region.
- **Rationale:** Cloudflare placement is a latency mechanism, not a country guarantee (EST).
- **Alternatives:** Proxy providers with country egress; Treat geography as best effort
- **Evidence that would change it:** A source that serves different catalogs by visitor country.
- **Provenance:** Separation of execution region vs market is EST.

## DEC-08 · Confirmed budget; proposed launch workload — BUDGET CONFIRMED / WORKLOAD PROPOSED

- **Recommended default:** Maximum USD 50/month in recurring service costs for the initial system. This accepts only the spending constraint, not other architectural proposals.
- **Rationale:** Preserve uncertainty reserve and gate paid work at admission. Cost assumptions are not measurements.
- **Alternatives:** —
- **Evidence that would change it:** Price all required services and measure database activity, source access, model fallback and human review before launch.
- **Provenance:** See cost.html#launch-budget for engine-derived estimates.

## DEC-09 · Event ordering and idempotency — EST

- **Recommended default:** Stable event IDs, per-aggregate revisions, dependency revisions and a product-service inbox; apply before acknowledgment.
- **Rationale:** Required by the baseline.
- **Alternatives:** —
- **Evidence that would change it:** —
- **Provenance:** EST

## DEC-10 · Where shipping evaluation runs — PROP

- **Recommended default:** POST /v1/shipping/evaluations on the product service, using accepted policy projections.
- **Rationale:** Serving behaviour belongs to the product service; policy updates change summaries without a product scrape.
- **Alternatives:** Resolver dry-run endpoint; Client-side evaluation
- **Evidence that would change it:** Need for operator-side what-if on unaccepted policy versions.
- **Provenance:** PROP


# Current architecture review decisions

## id

DJ-11

## group

now

## priority

0

## question

Launch with two bounded scrapers and a reserved operating budget?

## recommendation

Propose two sources with 200 listings each, daily refreshes and application admission quotas. Price every required recurring service within the confirmed USD 50/month ceiling.

## reason

A narrow workload leaves room for uncertainty while measuring real source behavior.

## alternatives

- Reduce listings or browser dependence if the service inventory does not fit.
- Defer paid launch until required services and source behavior are priced.

## consequences

Optional browser, LLM and replay work pauses before the reserve is consumed. Accepted data stays available with honest stale/deferred status.

## status

Proposed — awaiting Jonathan’s acceptance

## evidence

Itemized service prices and allowance allocation; database active time; parser failures; review effort; measured source access.

## link

cost.html#launch-budget

## id

DJ-09

## question

Adopt tenant-private catalogs as the initial baseline?

## recommendation

Yes: tenant isolation from day one, with catalog identity modeled separately.

## reason

Ownership, access, and publication stay explicit without deciding shared governance prematurely.

## alternatives

- Shared catalogs plus private overlays
- Single implicit global catalog

## consequences

Cross-tenant sharing later needs migration and permissions design; current keys and events carry tenant and catalog.

## status

Proposed — Jonathan’s acceptance needed

## evidence

Confirm intended tenants, sharing needs, and public publication authority.

## link

atlas.html#ADR-008

## group

now

## priority

1

## id

DJ-10

## question

Who may authorize public publication?

## recommendation

An operator admin with publications:write releases an accepted revision and allowlisted explanations.

## reason

Automatic internal acceptance is not consent to expose source evidence or operational metadata.

## alternatives

- Explicit per-catalog publication policy after review
- Every accepted fact public by default

## consequences

An accepted correction may remain private. Public item, listing and inventory views move together only when its authorized release applies; withdrawal timing still needs an agreed operational target.

## status

Proposed — Jonathan’s acceptance needed

## evidence

Approve release roles, fields, observation-metadata permission, and withdrawal expectations.

## link

data.html#publication

## group

now

## priority

2

## id

DJ-01

## question

Physical database topology?

## recommendation

Start with one managed PostgreSQL instance, separate resolver and product schemas, and service-specific database roles.

## reason

Keep transaction and operations complexity bounded during the initial slice.

## alternatives

- Shared instance (recommended)
- Separate instances now
- PostgreSQL resolver + D1 product

## consequences

This keeps the first deployment smaller, but the services share a database failure boundary. Moving to separate instances later adds an explicit migration. Any topology or runtime must include all required recurring services within the confirmed USD 50/month ceiling; measure active database time before selecting it.

## status

Open — Jonathan’s decision needed

## evidence

SPK-01 must prove transaction and role isolation through the selected driver and pool.

## link

atlas.html#ADR-002

## group

now

## priority

7

## id

DJ-02

## question

Use relational accepted state with a transactional outbox?

## recommendation

Keep accepted facts in relational tables, preserve immutable evidence and decisions, and commit each integration event with its state change.

## reason

Relational state supports operational queries; the outbox reliably carries accepted changes.

## alternatives

- Relational + outbox (recommended)
- Event sourcing for identity aggregates only
- Full event sourcing

## consequences

Operational queries stay straightforward. Recovery depends on coordinated snapshots and retained events; the bounded outbox is not a permanent event-sourcing log.

## status

Open — Jonathan’s decision needed

## evidence

SPK-01 proves transaction atomicity; SPK-05 proves snapshot and retained-tail recovery.

## link

atlas.html#ADR-003

## group

now

## priority

3

## id

DJ-03

## question

Outbox retention window?

## recommendation

Keep bounded event retention with rebuild leases and durable live-consumer protection. Treat 14 days only as a placeholder until recovery is measured.

## reason

Retained events must outlive recovery lag; a lease overrides ordinary pruning.

## alternatives

- Bounded window (recommended)
- Permanent outbox as replay log

## consequences

An active rebuild or stalled consumer can extend storage beyond the age window. Set the final duration and alerts from measured rebuild time and lag.

## status

Open — Jonathan’s decision needed

## evidence

SPK-05 measures pruning during rebuild, progress after cutover, gaps, restore fencing and peak retention growth.

## link

atlas.html#SPK-05

## group

spike

## priority

1

## id

DJ-04

## question

Recovery objectives (RPO/RTO) for the resolver database and evidence store?

## recommendation

Set the maximum tolerable loss of accepted data and the maximum service outage for the resolver and evidence store before choosing backup commitments.

## reason

Recovery targets determine backups, cost and incident procedures.

## alternatives

- Provider PITR defaults
- Stricter targets with replicas
- Evidence store replication

## consequences

These targets determine backup/PITR plans, restore procedures and cost. Product projections can be rebuilt; lost source evidence and decisions cannot be assumed recoverable.

## status

Open — Jonathan’s decision needed

## evidence

Jonathan supplies business loss/outage tolerances; SPK-05 measures whether the proposed restore and rebuild can meet them.

## link

atlas.html#ADR-004

## group

now

## priority

4

## id

DJ-05

## question

Who approves identity-relevant attribute definitions and item splits?

## recommendation

Require a human to approve identity-relevant definitions and splits, and separately authorize activation of a backfilled, collision-free identity generation.

## reason

Identity changes can split products and invalidate downstream mappings.

## alternatives

- Human always (recommended)
- Auto-publish when deterministic evidence is unanimous

## consequences

Captures and replay remain pinned to explicit rules. Unresolved splits hold affected claims and delay activation instead of silently changing identity.

## status

Open — Jonathan’s decision needed

## evidence

Review ownership of definition approval, split decisions and rule activation; then exercise concurrent capture/backfill in the implementation.

## link

atlas.html#ADR-005

## group

now

## priority

5

## id

DJ-06

## question

First real source for measurements?

## recommendation

Keep Pantry & Pour as a deterministic fictional fixture; choose a real authorized source separately

## reason

A fictional fixture proves deterministic behavior, not access or source economics.

## alternatives

- Public feed with stable identifiers
- Partner API with permission
- Browser storefront after feasibility review

## consequences

The fictional Pantry & Pour fixture keeps the implementation slice deterministic. Only an authorized real source can establish access, parser reliability, browser demand and cost.

## status

Open — Jonathan’s decision needed

## evidence

Confirm source permission and stable identifiers, then measure fetch success, extraction quality, freshness and human review workload.

## link

atlas.html#SPK-03

## group

now

## priority

6

## id

DJ-07

## question

Resolver runtime?

## recommendation

Trial Workers and Hyperdrive for intake, administration and job consumers, with portable domain code and a Node-container fallback if transaction requirements fail.

## reason

Keep domain logic portable while testing the proposed deployment.

## alternatives

- Workers + Hyperdrive (recommended)
- Node container near the database

## consequences

This avoids committing to a runtime before proving writer locks, transaction lifetimes and error handling. A failed spike changes deployment adapters, not domain contracts. Any topology or runtime must include all required recurring services within the confirmed USD 50/month ceiling; measure active database time before selecting it.

## status

Open — Jonathan’s decision needed

## evidence

SPK-01 covers transactional cursor contention, all-or-nothing writes, role boundaries and driver/pool behavior.

## link

atlas.html#SPK-01

## group

spike

## priority

2

## id

DJ-08

## question

Decision history retention?

## recommendation

Retain decision history as immutable records, with correction represented by a new linked decision.

## reason

Corrections need a durable explanation without rewriting earlier decisions.

## alternatives

- Permanent (recommended)
- Bounded with archival export

## consequences

Operators can explain how an identity changed. Storage, access control and eventual evidence-retention policy must support that audit history.

## status

Open — Jonathan’s decision needed

## evidence

Confirm retention and privacy requirements before final storage policy; restrict application roles from deleting decisions.

## link

atlas.html#ADR-003

## group

now

## priority

8

# Guide annotation — storage and authentication alternatives

Added for this system guide after workbench checkpoint 0.5.3 was copied. This section is not generated from `assets/fixtures-atlas.js`. It does not accept a stack. Only the USD 50 per month recurring-service ceiling is confirmed, and that ceiling is not a storage or authentication decision.

## Storage

These alternatives are already on the record. None is newly recommended here.

| Alternative | Where it is written | What it would mean | Status |
|---|---|---|---|
| One managed PostgreSQL instance, resolver schema and product schema, separate roles | DEC-01 recommended default; DJ-01; ADR-002 | Operational queries and the transactional outbox stay in one engine. The services share a failure boundary. | PostgreSQL as the baseline is EST. The topology is OPEN. |
| Separate database instances now | DJ-01 | Avoids a later split. Raises cost and operations before the first slice has measured them. | OPEN alternative. Not chosen. |
| PostgreSQL for the resolver and D1 for the product projection | DJ-01; ADR-010 | Two stores and two failure modes. ADR-010 still says to begin with PostgreSQL projections. | OPEN alternative. Not chosen. |
| D1 for the whole database | DEC-01; ADR-007 | Cloudflare-native SQLite semantics. Needs a spike that reproduces the outbox transaction, JSON queries, and the expected volume. | Alternative under evaluation. SPK-06 is conditional and has not been run. |
| Self-hosted PostgreSQL | DEC-01 | Same engine, different operator. Still has to fit the confirmed ceiling once it is a recurring service. | OPEN alternative. Not chosen. |
| Files by checksum on the local disk | ADR-007, unpaid first slice | The artifact port during local work. Not the hosted evidence store. | Proposed local adapter. |
| Private object storage (R2 in the hosted sketch) | ADR-007 hosted adapters | Write-once objects addressed by checksum. The provider is not chosen by this guide. | Proposed hosted adapter. Not authorized. |
| Filesystem, in-memory, and PgJobTransport | ADR-007 | Test and fallback adapters. Not production stores. | Recorded for tests. |
| Dedicated search | Deferred projection-store note; SPK-04 | Add it only if representative product queries need it. | Deferred. Not a current decision. |

Evidence that would change the database row is unchanged: a D1 spike that reproduces the outbox-in-transaction, JSON querying, and expected volume inside published limits. DJ-01 still waits on SPK-01 for transaction and role isolation through the selected driver.

## Authentication

The trust-boundary recommendation is PROP. The identity-provider choice is OPEN. This annotation does not close it.

| Alternative | Where it is written | What it would mean | Status |
|---|---|---|---|
| One identity provider, or a small token service, issuing OIDC sessions for operators and OAuth2 client-credentials for each collector instance | Trust boundaries, recommendation | Tokens are checked with JWKS, tenant and source claims, and a revocation registry. Queue messages still carry no secrets. | Proposed shape. Provider not chosen. |
| Managed OIDC provider | Trust boundaries, consequences | An outside provider holds operator login and collector tokens. | OPEN. Not chosen. |
| Small self-hosted token service | Trust boundaries, consequences | The project runs the token issuer. Still uncosted inside the USD 50 ceiling. | OPEN. Not chosen. |
| Cloudflare Access in front of the admin origin | Trust boundaries, recommendation | An optional outer gate. It does not replace the session or the collector token. | Optional. Not required. |
| Custom HMAC request headers | Trust boundaries, recommendation | Earlier proposal. | Retired. Not an alternative to revive. |
| No paid identity provider on the local slice | ADR-007 local adapters; implementation plan | The fictional feed runs with local ports and a fake model. | Proposed for the unpaid slice only. |
| Simulated cryptography in the workbench | Trust boundaries; interface catalog | Scope checks run in the prototype. Real token cryptography, TLS, and the identity provider were not verified. | Unverified. |

Operator mutations in the proposal still require the server session and a matching origin plus synchronizer token. Collector registration cannot select another tenant or widen source grants. Public reads use TLS and a release allowlist. They do not use a consumer secret.

A Broadwater pilot checklist points at this annotation. It does not select a row.

