ops: record the allowance-shortfall manual-remediation ledger

The portal's SHORTFALL_REMEDIATED constant now carries only the OC charge
reference (de-PII'd from the public member-portal repo); the member
identity and the timeline of the manual reset live here, keyed on the
charge, plus the rationale for charging-keyed exclusion.
This commit is contained in:
inference-bot committed 2026-11-05 15:59:13 +00:00
1 parent a9edaa3e4b
commit b1a1c70e8a
1 file changed
+26
@@ -0,0 +1,26 @@
# Allowance shortfall remediation — manual-remediation ledger (2026-11-04/05)
The portal's shortfall mechanism (`derive_shortfalls` in
`member-portal/app/main.py`) credits a member's missing allowance whenever OC
realigned a charge onto the collective billing day and truncated a paid cycle.
Each credit is keyed on the OC charge reference (`tx_…` publicId) so a re-run
never credits twice.
## Entries in `SHORTFALL_REMEDIATED` (code constant, no PII by design)
| OC charge reference | Why it is excluded from automatic shortfall crediting |
|---|---|
| `[redacted member reference]` | The truncated cycle this charge created was already made whole by a **manual allowance reset on 2026-11-04**, performed outside the mechanism (before the automatic path shipped). The member joined mid-October; OC moved their next charge to the 2 Nov common billing day, so their cycle ran ~17 days. The reset re-anchored the allowance to the member's own join day, which is the policy now in code. Later charges of this member form new cycles and are credited normally by the automatic path. |
The member's identity is in the portal `credit_ledger` / `members` tables
(the credit row itself) — the public portal repository deliberately carries
only the charge reference (audit H2, 2026-11-05: the constant used to embed
the member's email and billing timeline; the portal repo is public).
## Why the exclusion is keyed on the charge, not the member
`derive_shortfalls` reads charge history from OC's order list; the charge that
truncated the cycle is the idempotence key everywhere else in the flow
(`credit_reference_exists`). Keying the manual-remediation exclusion on the
same charge means a sweep re-run can neither double-credit the charge nor
skip a genuinely new truncated cycle for the same member.