Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 61 additions & 0 deletions DECISIONS.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,67 @@ Each entry:

---

## Canonical & Data Model

### 2026-07-29 — Default period for any unqualified "annual" figure is cy2025
- **Decision:** When canonical states a figure without a period, it means
cy2025 (2025-01-01 … 2025-12-31). Every other period is a named variant,
not a discrepancy.
- **Why:** Tools kept reading as "failing" against canonical when they were
measuring a different window, not a different number — every prior headline
figure was silently trailing-36-months (e.g. DIO 127.3=t36m, cy2025=134.6).
cy2025 is chosen over other defaults because scan data ends 2025-12-27, so
trailing-12-months resolves to the identical window — it collapses two
candidate defaults into one definition instead of leaving rival readings.
- **Scope:** global — `reference/CINDERHAVEN_CANONICAL.md`,
`reference/canonical_values.yml`, every downstream tool citing canonical.
- **Do not:** cite a canonical figure without its period; treat a
named-variant period as drift.

### 2026-07-29 — There are five margin lines; always name the basis
- **Decision:** Cinderhaven has five distinct, all-real margin figures —
gross-at-standard (51.98%), contribution after commercial costs (49.01%),
gross-at-landed (~43.5%, legacy), loaded-at-standard (42.5%), and
loaded-at-actual (42.3% blended). Cite the basis with the number, always.
- **Why:** They differ because a CFO expects them to (COGS-narrow vs
fully-loaded contribution are different P&L lines). Presenting one without
its basis reads as the can't-keep-numbers-straight defect this warehouse's
canonical exists to kill. Loaded-at-standard is flat by construction (frozen
standard); loaded-at-actual carries the PPV compression.
- **Scope:** global — anything quoting Cinderhaven margin.
- **Do not:** compute margin from `manufactured_cost_per_unit` and call it the
loaded margin (that is loaded-at-actual, not -at-standard); modify
`raw.sku_costs` wholesale/cogs to hit a spread target (moves every published
margin).

### 2026-07-29 — contract-to-cash's uncollected-receivables copy is wrong
- **Decision:** The narrative attributing part of the invoiced-vs-collected
gap to uncollected receivables must be rewritten. Uncollected receivables
are **$0** by construction.
- **Why:** `invoiced == gross_payments` to the cent because
`generate_remittances()` partitions every order into exactly one
retailer-month remittance and `net = gross − total_deductions`; the schema
has no aging bucket, bad-debt, or unpaid-invoice concept. The entire gap is
trade allowances, deductions, chargebacks, and a timing residual.
- **Scope:** contract-to-cash hero copy; any tool implying AR.
- **Do not:** present AR as a number; it is absent-structural, not zero.

### 2026-07-29 — The 22–55% SKU-margin-spread target was invented; retire it
- **Decision:** The "roughly 22–55%" SKU loaded-margin spread target is
retired as unsourced. The criterion is **width ≥ 30 points, position
inherited from `raw.sku_costs`**. Achieved and canonical: 25.81–60.94%
(35.1-point width).
- **Why:** The target was an invented illustration of "wide spread," same
class as the trade-spend trajectory and best-seller-worst-margin claims
already retracted. What mattered was width, and the build exceeds it. The
position is inherited from frozen wholesale/cogs; the only way to move it is
to modify protected pricing data, which moves every published margin.
- **Scope:** cost-side SKU margin; `fct_product_costs`.
- **Do not:** treat a red check against the old 22–55% as a real failure — the
check is wrong; this decision is the fix.

---

## Infrastructure & Ops

### 2026-07-02 — Stop guessing at cinderhaven-db's flypgadmin credential; rebuild or escalate instead
Expand Down
60 changes: 60 additions & 0 deletions HANDOFF.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,66 @@ For things that didn't work, see FAILURES.md.

---

## 2026-07-29 (wrap) — cost-side data model, production deploy, period-explicit canonical; all merged to main

**Started from:** Phase 1 complete (entry below). User directed the full
enrichment arc across several turns.

**Did (four arcs, all merged to main at `0ea3961` via squashed PR #2):**
- **Cost side.** New isolated `costing` schema — `fct_product_costs`,
`fct_inventory_snapshot`, `dim_suppliers`, `fct_supplier_invoices`, plus
production runs, inventory lots, lot balances, and a lot→shipment→store
bridge. Five named margin lines (gross-at-standard 51.98%, contribution
49.01%, gross-at-landed ~43.5%, loaded-at-standard 42.5% flat,
loaded-at-actual 42.3% blended). PPV carries the compression (standard
frozen at launch; actual walks 45.0→42.4→39.6). CCC 119.7 (t36m,
production). Additive-only: nine protected tables byte-identical before/after.
No cross-schema FKs (DROP SCHEMA raw CASCADE would silently drop them);
integrity in the generator + `tests/test_costing_integrity.sql`. Stored
totals are GENERATED STORED.
- **Production deploy.** Dispatch-only workflow `deploy-costing.yml` with a
pre-flight guard (halts if `costing` holds rows unless force_recreate).
First install — `costing` did not previously exist. Every acceptance figure
matched the replica; integrity clean. One-cent divergence on
`fct_retailer_payments` + `mart_channel_contribution` diagnosed as a
different seed run, not tampering (it foots, raw=mart, only float-rounded
currency columns differ).
- **Period-explicit canonical.** Rebuilt `CINDERHAVEN_CANONICAL.md` →
`reference/` so every value carries a basis AND a period; added
machine-readable `reference/canonical_values.yml` keyed
`metric.basis.period`; root pointer left behind. Default period **cy2025**
(≡ trailing_12m). Headline: prior canonical figures were silently
trailing-36m, which is why cy2025 tools read as failing (DIO 127.3=t36m,
cy2025=134.6). Guards hard-fail if the file is missing;
`verify_canonical.py` reads the YAML. Three findings recorded not smoothed:
2024 revenue is a velocity peak on a shrinking door base; authorizations
9,943/0/49 is an initial-load artifact; promo spend + deauths are zero in
cy2025 (windows ended 2024). Values VERIFIED-AGAINST-PRODUCTION via
read-only workflow.
- **CI bug fixed.** `canonical-drift.yml` had hardcoded the literal string
`REDACTED` as the Postgres password since `a4cebc4` — the drift check had
**never** authenticated. `f97abbf` interpolates `$POSTGRES_PASSWORD`; drift
now green against production.

**State:** main `0ea3961`, clean. PR #1 (Phase 1 + cost side) and PR #2
(period-explicit canonical) both merged. Designated branch recreated from main
for this wrap. `costing.*` live in production, nine protected tables intact,
**nothing wired to `costing.*`** — no tool, no dbt model, no live app.
Local replica is ephemeral to the container. flyctl/Fly creds are NOT in the
session; all production work went through dispatch-only GitHub Actions
(FLY_API_TOKEN + POSTGRES_PASSWORD secrets). Remote branch deletion is blocked
from the session env (git proxy + REST both refuse); user deletes branches.

**Next (post-CEO-window, separate work):** wire tools to `costing.*` one at a
time (recall-blast-radius, the four margin tools, Spin Rate migration, etc.).
The four UNSOURCED hypotheses (trade-spend trajectory, best-seller-worst-margin,
master-data degradation, deduction learning curve) still need SPINS/Nielsen
checks before becoming demo numbers. `reference/COST-SIDE-DATA-SPEC.md` was
referenced by the user but never existed in the repo — schemas were designed
from the prompt.

---

## 2026-07-29 — Phase 1: canonical verified against Postgres, both contradictions resolved, pre-Phase-2 baseline recorded

**Started from:** Two-phase instruction from user. Phase 1 (measure,
Expand Down
Loading