Skip to content

Step 2e — move entitlements onto a shape both grant formulas agree on - #805

Draft
mitchelljkotler wants to merge 1 commit into
pricing-models-migrationfrom
pricing-models-entitlement-shape
Draft

Step 2e — move entitlements onto a shape both grant formulas agree on#805
mitchelljkotler wants to merge 1 commit into
pricing-models-migrationfrom
pricing-models-entitlement-shape

Conversation

@mitchelljkotler

Copy link
Copy Markdown
Member

Stacks on #800.

Clients compute base + max(quantity − minimum_users, 0) × per_user; the target is base × quantity. With minimum_users = 1 and per_user = base those are the same expression for every quantity ≥ 1 — so MuckRock and DocumentCloud can switch formulas whenever they like, in either order, and no number moves.

Changes no prices. Entitlement.resources is the only thing written.

What to look at

  • The precondition, not the transform. The identity is exact at quantity 1 and nowhere else. Applied to a line still holding 30 blocks, an Organization grants 50 + 29×50 = 1,500 instead of 300 — silently, to every client at once. The command refuses while any non-pack line is above 1 and names the organizations. Packs are exempt: base × q is what a pack means.
  • Packs transform in the opposite direction. A pack's value lives in per_user with base at zero. Applying the tier transform sets per_user = 0 and grants nothing — the trap 0082 wrote itself a note about. Pack vs tier is decided by plan membership, not by inspecting numbers, so it stays right for an already-converted pack.
  • Entitlements with no base_* key are untouched — Sunlight's research hours don't scale with blocks.

QA

migrate_entitlement_shape --dry-run prints each entitlement's grant at the quantities its subscribers actually hold, under both formulas. Every row should read the same number three times.

🤖 Generated with Claude Code

https://claude.ai/code/session_0151rwxtvLg1vKEiz7XsJfzf

Step 2e.  Clients compute base + max(quantity - minimum_users, 0) *
per_user; the target is base * quantity.  With minimum_users = 1 and
per_user = base those are the same expression for every quantity >= 1, so
MuckRock and DocumentCloud can switch formulas whenever they like, in
either order, and no number moves.  That is the whole point: it removes
the need for anyone to deploy in step with anything.

Changes no prices.  Entitlement.resources is the only thing written.

Two things carry the weight, and neither is the transform:

The precondition.  The identity is exact at quantity 1 and at no other
quantity -- applied to a line still holding 30 blocks, an Organization
grants 50 + 29*50 = 1,500 instead of 300, silently and to every client at
once.  So the command refuses while any non-pack line is above 1 and names
them, rather than trusting that the pricing migration ran first.  Packs
are exempt: base * q is exactly what a pack means.

The direction.  A pack's value lives in per_user with base at zero,
because that is the only shape the current formula can scale.  Its value
moves the other way -- applying the tier transform to a pack sets
per_user = 0 and grants nothing at all, which is the trap 0082 wrote
itself a note about.  Classified by plan membership rather than by
inspecting the numbers, so it stays right for a pack that has already been
converted.

Entitlements with no quantity-scaled key are left untouched: Sunlight's
research hours buy no more with more blocks, and a bare feature_level is
not a quota.  The dry run prints each entitlement's grant at the
quantities its subscribers actually hold, under both formulas, because the
arithmetic is the thing worth checking.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants