worktree-pricing-plans-spec
Carloku pricing: the spec, four plans, and the first one built.
What lands here
Docs. The customer-facing commercial model, reviewed over three rounds by GPT-6 via codex with every findings file committed unedited beside it:
docs/superpowers/specs/2026-09-07-carloku-pricing-plans-design.mddocs/superpowers/plans/2026-09-08-invoice-grade-statements.md— built heredocs/superpowers/plans/2026-09-10-store-egress-and-durability-meters.md— needs a fourth design round, marked in its own header. Do not execute it.
Code. Plan one: the first three of the prerequisites that gate raising any invoice. Statements are used for cost modelling today and were not safe to bill from, for three reasons:
- Coverage meant "any source reported", so a statement could claim a full month while missing every day of egress. It is now counted per collection source, strictly — a day counts only when every discovered box of that source reported it, because one healthy box must not vouch for a silent one.
- Usage was re-attributed against the live registry on every hourly pass, and retired routes are hard-deleted. An account that removed an app mid-month silently stopped being billed for hours it had already used. Ownership now comes from the day's census, which already exists so that metering has history the registry cannot give it.
- The pass derived one month from
nowand never revisited it, while host metrics roll an hour up only after it ends — so a month's last hours landed after nothing was updating that month. It now runs a previous-month period onbillPass's pattern, and closes the month past the same grace so it stops moving under a bill. Closure is enforced insideUpsertStatement's CAS loop, against the same read that produced the ETag, because a caller-side check races the other console.
The bug the whole-branch review caught
Worth reading if you review nothing else. The three fixes composed into a false completeness signal: SourceDays reported metrics meters complete even on days whose attribution had come from the live-registry fallback — a census with no Units map, which is every census written before this branch. Task 3's irreversible closure then froze the wrong number and stamped it trustworthy. On the first tick after deploying, the previous month would have been swept with pre-Units censuses, closed, marked complete, and every future write refused.
Fixed by gating census completeness on whether the census can actually answer "who owned this unit", and requiring a full census month for metrics-sourced meters. The edge meters are deliberately exempt: egress and requests are attributed from row.Account stamped into the edge day at collection time, so they satisfy ownership by construction.
A seventh prerequisite, found and recorded not built
Completeness asks whether every discovered box reported a day, and boxes are discovered by listing what has ever written. So a box provisioned on 2 September has no August day objects, and August reads incomplete for every account — permanently, once closed. Any month in which fleet capacity changed can never report complete, which is most months on a growing platform. Scoping discovery to "boxes that produced something" would reintroduce exactly the hole this branch closes. It needs a box first-seen/decommissioned-at record; recorded in the spec's Overage section.
Accepted bounds, all fail-safe
Every one of these refuses to bill rather than billing wrongly:
SourceDaysis platform-wide, matchingCoveredDays's existing semantics.MeterCompleteis never true for the two fleet box-hour meters; they come fromfleetMeters, which reads objects the sweep never touches.app_monthsis gated on a census property it does not strictly need.- A route created and deleted between two daily censuses still falls to the platform account. Unchanged from before.
- Box-side durable usage writes are deferred to their own plan.
usageFlushstill drops a window on a failed write, so a day can be silently short. This is why plan one's own self-review says these three tasks are necessary but not sufficient for billing.
Verification
go build ./..., go vet ./..., gofmt -l . and the full go test ./... -count=1 are clean, before and after merging main (132 commits) into the branch. Forge CI passed on the pre-merge head; the post-merge run is what gates this. Twenty-seven of the branch's own tests run and pass after the merge. Each task had its own review and fix round, then a whole-branch review and one fix wave, then a scoped re-review that verified the two amended tests kept their original subjects.
Nothing here bills anyone, talks to Stripe, or reads a plan definition.
Discussions
- No discussions on this branch yet.
Tasks
- No tasks yet.
Activity
- paul@keymail.dev pushed 2cde9ee5e Merge remote-tracking branch 'origin/main' into worktree-pricing-plans-spec
- paul@keymail.dev pushed 852290c11 pricing: completeness must not vouch for attribution it never verified
- paul@keymail.dev pushed 1775c912b pricing: record a seventh billing prerequisite, the box lifecycle record
- paul@keymail.dev pushed a220b8339 usage: fix statements-pass review findings
- paul@keymail.dev pushed 5c75701cd usage: close the month, and catch up the one before it
- paul@keymail.dev pushed 170306adf usage: resolve unit ownership as of the usage day
- paul@keymail.dev pushed 847da77c4 usage: cover the two review-flagged gaps in per-source day counting
- paul@keymail.dev pushed edcba3af2 usage: count statement coverage per source, not per day
- paul@keymail.dev pushed e70860c1e pricing: rule that store egress charges only observed usage
- paul@keymail.dev pushed 3d263493f pricing: codex round three on plan two, unedited
- paul@keymail.dev pushed a5170bca2 pricing: plan two round-two fixes
- paul@keymail.dev pushed 89a24feab pricing: rewrite plan two against seventeen codex findings
- paul@keymail.dev pushed af53b6253 pricing: implementation plan for the store egress and durability meters
- paul@keymail.dev pushed 25f6b68c4 pricing: the last two plan gaps codex found
- paul@keymail.dev pushed 165c5101c pricing: fix the statements plan's test code, which did not compile
- paul@keymail.dev pushed aa938bf4f pricing: revise the statements plan against the codex review
- paul@keymail.dev pushed c30d059b5 pricing: implementation plan for invoice-grade statements
- paul@keymail.dev pushed c16f92010 pricing: the 50% discount draws on the pool, and the pool rises to 15%
- paul@keymail.dev pushed 4c3000c43 pricing: round-three corrections; the review cycle converges
- paul@keymail.dev pushed 1bd3f19db pricing: round-two revisions, and Business drops to a 30k write inclusion
- paul@keymail.dev pushed 4d545db38 pricing: revise the spec against all fourteen codex findings
- paul@keymail.dev pushed ae68c79ac pricing: codex findings on the pricing spec, unedited
- paul@keymail.dev pushed a96fb4e29 pricing: codex review brief for the pricing spec
- paul@keymail.dev pushed 1dc24945d pricing: annual plans, the affordability index, and the published books