carlos / platform Public

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.md
  • docs/superpowers/plans/2026-09-08-invoice-grade-statements.md — built here
  • docs/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:

  1. 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.
  2. 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.
  3. The pass derived one month from now and 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 on billPass's pattern, and closes the month past the same grace so it stops moving under a bill. Closure is enforced inside UpsertStatement'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:

  • SourceDays is platform-wide, matching CoveredDays's existing semantics.
  • MeterComplete is never true for the two fleet box-hour meters; they come from fleetMeters, which reads objects the sweep never touches.
  • app_months is 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. usageFlush still 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.

Commits 24
Discussions 0 0 open
Tasks 0/0 done

Discussions

  • No discussions on this branch yet.

Tasks

  • No tasks yet.

Activity