Readiness, enablement and handoff: bands.p3 resolved with the approved explanation; currency_options stated as the code enforces it; what is still code apart from approvals
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
4 files changed,
+62
−13
.claude/HANDOFF.md+3 −1implementation/carloku-paid-launch/ENABLEMENT.md+20 −4implementation/carloku-paid-launch/READINESS.md+38 −7implementation/carloku-paid-launch/stripe-provisioning.md+1 −1
CI passed — run details
diff --git a/.claude/HANDOFF.md b/.claude/HANDOFF.md| index 88c63dc85..85eb9dfb8 100644 |
| --- a/.claude/HANDOFF.md |
| +++ b/.claude/HANDOFF.md |
| @@ -26,11 +26,13 @@ Branches (all on the forge, none merged; the local gate is not CI): |
| **NEEDED:** |
| - Paul, commercial: approve the 36 amounts as an `approved` book version (approval L) together with the USD/GBP overage rates and floors in `OVERAGE-RATES-PROPOSAL.md`, or state other figures; the HALF code word; the proration policy (B); the partial-month rule (C). |
| -- Paul, copy: the console billing page's 40 strings; the store-refusal copy (`OUTSTANDING.md` 19g); a new sentence for the pricing page's `bands.p3` ("The euro price is what is charged" is wrong under fixed currencies); the approved pricing and currency strings themselves need nothing more. |
| +- Paul, copy: the console billing page's 40 strings; the store-refusal copy (`OUTSTANDING.md` 19g). `bands.p3` is done: the approved currency explanation replaced the converted-euro sentence (site `e091e3f`, 07:0x); it now reads the same as the note under the currency selector. |
| - Paul, rulings: evidence for a held bucket-hour (J); storage on a bucket a store has left (K); the cutover note (M: purchases before the book stay legacy EUR; binary first, variables second). |
| - Scoped approvals, prepared as plans only: Stripe test mode (E) for the fence test and the rehearsal; Stripe live provisioning (F) after the approved book; the Cost and Usage Report export and the scratch-object write (G); Path B on a dev box (H). |
| - Reviews to read when they land: the currency branch's twelfth (`logs/opus-currency-review12.md`, `astra-currency-review12.md`) and the replicator's tenth (`opus-replicator-review10.md` is in; `astra-replicator-review10.md` pending). |
| +**STILL TO BUILD (code, not approvals; no fake completes these):** quantity reduction at renewal (`OUTSTANDING.md` 14), the Free tier (15), dormancy and pool accounting (16), per-line tax codes across a change (17), the operator doors (18, plus the quantity-history gap door and a rejected-events listing), the meters' own code (replicator unwired with deep items open; store transfer has no source), the two key-memory defects (7, 9). `READINESS.md` has the list with what each means. The tests on the currency branch establish the subscription and currency path against fakes, nothing beyond it. |
| + |
| **RECOMMENDED:** |
| - Read the twelfth currency review. If it confirms round eleven's fixes (both accepted rounds ten and eleven with fixes; the fixes are in `25487506` and `781bb1c2`) and CI is green on the tip, merge the currency branch into this branch: a merge commit pushed to this branch, as the observe-routes fix was at `47c97fa6` (`amadan branch merge` lands a branch on main and is not what this step is), then gate the merged tip. If it does not confirm, the next commit answers it the same way. Rule on K to let the storage branch follow. |
| - Publish the approved book version as soon as L is given; it is a new entry in `internal/plans/pricebook.json`, the export regenerated and copied to the site, and the 36 lookup keys renamed. |
diff --git a/implementation/carloku-paid-launch/ENABLEMENT.md b/implementation/carloku-paid-launch/ENABLEMENT.md| index eb9d2da9a..8971fd6e5 100644 |
| --- a/implementation/carloku-paid-launch/ENABLEMENT.md |
| +++ b/implementation/carloku-paid-launch/ENABLEMENT.md |
| @@ -17,7 +17,7 @@ disagree, `stripe-provisioning.md` is wrong and this file says so. |
| | Thing | Count | Where it is defined | Exists today | |
| | --- | --- | --- | --- | |
| | Products | 3 (personal, community, business), tax codes `txcd_10102001`, `txcd_10102001`, `txcd_10102000` | plan step 1 | no | |
| -| Prices | 36: 3 plans x 4 bands x 3 currencies, yearly, licensed, tax exclusive, one currency each, no `currency_options` | plan step 2; `internal/plans/pricebook.json` | no | |
| +| Prices | 36: 3 plans x 4 bands x 3 currencies, yearly, licensed, tax exclusive, one currency each; no currency option but the price's own (Stripe may answer an expanded `currency_options` with an entry under the price's own currency at its own amount; that passes, any other entry is refused) | plan step 2; `internal/plans/pricebook.json` | no | |
| | Coupons | 2 (50% forever with the public code HALF; 100% house, no code) | plan step 3 | no | |
| | Portal configuration | 1, locked | plan step 4 | no | |
| | Webhook endpoint | 1, six events, API `2025-02-24.acacia` | plan step 5 | no | |
| @@ -34,8 +34,14 @@ Amounts are per member per year in the currency's minor unit, exactly |
| `metadata[terms_version]=2026-09-07-v1`, `metadata[price_book]`, |
| `metadata[currency]`, `metadata[plan]`, `metadata[band]`. The console |
| compares the five metadata values, the price's own `currency` and |
| -`unit_amount`, `tax_behavior`, the recurring interval and usage type, and the |
| -absence of `currency_options`, against the book before it sells on a price. |
| +`unit_amount`, `tax_behavior`, the recurring interval and usage type, and |
| +that `currency_options` holds nothing but the price's own currency at its |
| +own amount (`priceCurrencyOptionsAreOwn`; `stripe-provision.sh --check` |
| +applies the same rule), against the book before it sells on a price. The |
| +provisioning script's step-2 notes still say "no `currency_options`, ever"; |
| +that wording is to be aligned with the rule in the next currency-branch |
| +commit (the plans test reads the script's text, so it is not changed |
| +mid-review). |
| | Plan | Currency | A | B | C | D | |
| | --- | --- | --- | --- | --- | --- | |
| @@ -175,7 +181,7 @@ scope. Those that gate enabling payments, plus what this run added: |
| | # | Approval | State after the night | |
| | --- | --- | --- | |
| -| A | Copy | Pricing page grouped review and the five currency strings: approved 2026-10-01 and applied. Still open: the HALF code word, console billing page copy (40 strings), store-refusal copy. One approved string is now wrong: `bands.p3`, "The euro price is what is charged", under fixed currencies; it needs a new sentence and its own review | |
| +| A | Copy | Pricing page grouped review and the five currency strings: approved 2026-10-01 and applied. `bands.p3` ("The euro price is what is charged") replaced on 2026-10-02 by the approved currency explanation drafted for that slot (site `e091e3f`). Still open: the HALF code word, console billing page copy (40 strings), store-refusal copy | |
| | B | Proration policy | open | |
| | C | Partial-month rule | open | |
| | E | Stripe test mode | open; needed before the fence test and the rehearsal | |
| @@ -199,5 +205,15 @@ approvals granted. It does not mean payments switched on. |
| every commit, gate log, review verdict and CI run. |
| - Not code: approvals A (remaining parts), B, E, F, L, M; the test-mode |
| rehearsal; the live provisioning; the first live proof. |
| +- Still code, before the complete metered model can invoice or team plans |
| + can be sold, and not completed by any test against a fake: quantity |
| + reduction at renewal (`OUTSTANDING.md` 14), the Free tier (15), dormancy |
| + and pool accounting (16), per-line tax codes across a change (17), the |
| + operator doors (18, plus the quantity-history gap and the rejected-events |
| + listing the currency reviews name), the two meters' own code (the |
| + replicator branch is unwired with deep items open; the store transfer |
| + meter has no code because it has no source), and the two open defects |
| + past Stripe's key memory (7, 9). Approvals G and H gate the meters' |
| + deployment, not their completion. |
| - Not part of enabling subscriptions, still part of the complete metered |
| model: items 1 to 4 and 6 to 9 of `OUTSTANDING.md`. |
diff --git a/implementation/carloku-paid-launch/READINESS.md b/implementation/carloku-paid-launch/READINESS.md| index bf55c4d87..4e7b2d56d 100644 |
| --- a/implementation/carloku-paid-launch/READINESS.md |
| +++ b/implementation/carloku-paid-launch/READINESS.md |
| @@ -86,16 +86,47 @@ reconcile, calculation, invoice and recovery tests in |
| ## Approvals needed to enable |
| -A (remaining parts: HALF code word, console billing copy, store-refusal copy, |
| -a new `bands.p3` sentence), B, C, E, F, L (the approved book version and the |
| -USD/GBP overage rates in `OVERAGE-RATES-PROPOSAL.md`), M (the cutover note). |
| -Each is scoped in `ENABLEMENT.md` section 8 and `OUTSTANDING.md`. |
| +A (remaining parts: HALF code word, console billing copy, store-refusal |
| +copy), B, C, E, F, L (the approved book version and the USD/GBP overage |
| +rates in `OVERAGE-RATES-PROPOSAL.md`), M (the cutover note). Each is scoped |
| +in `ENABLEMENT.md` section 8 and `OUTSTANDING.md`. |
| + |
| +## Still to build, apart from any approval |
| + |
| +These are code, not approvals, and no test against a fake completes them. |
| +What the tests above establish is the subscription and currency path as |
| +modelled; the complete metered model and team plans need the following |
| +built and reviewed first (numbers are `OUTSTANDING.md` items): |
| + |
| +- Quantity reduction at renewal (14): absent; a renewal bills the old |
| + quantity, so team plans cannot be sold. |
| +- The Free tier (15): no entitlement, app cap, storage refusal, per-plan |
| + idle or flush-only class. |
| +- Dormancy archive and warnings, recognised-revenue pool accounting, the |
| + books site (16). |
| +- Per-line tax codes for a month spanning two codes (17; it holds with a |
| + review today). |
| +- Operator doors (18): the `carlos` verbs for the existing doors, a |
| + statement rebuild for a closed month, bucket-ownership backfill; and, |
| + from the currency reviews, a door to clear a quantity-history gap whose |
| + cause is established, and a listing of rejected webhook events. |
| +- The meters' own code: replication writes (the replicator branch, unwired, |
| + with the deep items listed in its row; approval H gates deploying it, not |
| + finishing it) and store transfer (no code, because no source; approval G |
| + gives it a source). |
| +- The two open defects past Stripe's key memory (7, 9). |
| + |
| +Approvals E and F then prove the subscription path against Stripe; nothing |
| +above is proven by the fakes. |
| ## Known defects and conflicts, open |
| -- `bands.p3` on the pricing page says the euro price is what is charged; |
| - under fixed currencies that is wrong. Approved copy; not edited; needs its |
| - own review. |
| +- `bands.p3` on the pricing page: resolved 2026-10-02 (site `e091e3f`). |
| + The sentence that promised a converted euro price is replaced by the |
| + approved currency explanation drafted for that slot, "Choose USD, EUR or |
| + GBP for your subscription and usage bills." (copy-review/currency); the |
| + same sentence is also the control note under the currency selector, so it |
| + appears twice on the page. Every other string is as approved. |
| - `OUTSTANDING.md` items 7 and 9 (late requests past Stripe's key memory) |
| are open defects, held, not waived. |
| - The replicator's deep open items after its eighth review are in its |
diff --git a/implementation/carloku-paid-launch/stripe-provisioning.md b/implementation/carloku-paid-launch/stripe-provisioning.md| index ad67c8fc8..f99251ad7 100644 |
| --- a/implementation/carloku-paid-launch/stripe-provisioning.md |
| +++ b/implementation/carloku-paid-launch/stripe-provisioning.md |
| @@ -99,7 +99,7 @@ Twelve prices, exactly the `required_catalog` in `stripe-live-readiness.json`. |
| Every price has these fixed fields: `currency=eur`, `tax_behavior=exclusive`, |
| `billing_scheme=per_unit`, `recurring[interval]=year`, |
| `recurring[interval_count]=1`, `recurring[usage_type]=licensed`. No |
| -`currency_options` on any price (it would switch off Adaptive Pricing, and the |
| +`currency_options` on any price beyond its own currency (the console refuses a price whose options name another currency; an entry under the price's own currency at its own amount passes, see ENABLEMENT.md section 2); the earlier text here said "it would switch off Adaptive Pricing, and the |
| console refuses a price that has any). Never pass `payment_method_types` |
| anywhere. |