carlos / platform Public

economics: spec and CLI docs record the #288 landing; backhaul meters never count as usage (#288 round 2)

The spec's 'ships dormant' paragraph and docs/site/cli.md now state
what shipped. PriceAccount's one generic meter walk (anyUsage, and its
JS twin) skips the backhaul meters, so the identity test can pin the
real invariant with an all-zero base. Zero-rate hint on the model row,
one sumMeter for the row, usage text reflowed, printer param named w.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Paul Campbell pushed by paul@keymail.dev cab3b09ed6f1d63654c5378970367e5877d1cefe parent aab5d35
7 files changed, +54 −16
  • docs/site/cli.md +9 −0
  • docs/superpowers/specs/2026-08-20-multi-region-ingress-design.md +11 −0
  • economics.go +10 −9
  • internal/console/economicsbackhaul_test.go +7 −0
  • internal/console/templates/economics.html +7 −4
  • internal/economics/compute.go +7 −1
  • internal/usage/usage.go +3 −2
diff --git a/docs/site/cli.md b/docs/site/cli.md
index ee9a45caf..eb1fac4f1 100644
--- a/docs/site/cli.md
+++ b/docs/site/cli.md
@@ -617,6 +617,15 @@ Operator only, and the console answers everyone else with the same bare 404
it gives an unknown route. A "not found" here almost always means your
account lacks the fleet-operator bit, not that you typed the path wrong.
+`carlos economics backhaul` shows what serving through region edges costs
+the platform this period: the part of each account's egress that was
+backhauled from its home box, priced at the rate card's inter-region
+$/GB and absorbed — it appears in nobody's bill.
+
+```sh
+carlos economics backhaul -period mtd
+```
+
### carlos status
`-live` prints what every box in the fleet last reported about itself:
diff --git a/docs/superpowers/specs/2026-08-20-multi-region-ingress-design.md b/docs/superpowers/specs/2026-08-20-multi-region-ingress-design.md
index e4d111856..70efa2bd9 100644
--- a/docs/superpowers/specs/2026-08-20-multi-region-ingress-design.md
+++ b/docs/superpowers/specs/2026-08-20-multi-region-ingress-design.md
@@ -391,6 +391,17 @@ decision (price backhauled bytes, or absorb them as a platform cost of
any-edge serving) can be made later on real data. Default taken tonight:
**absorbed**.
+*Amendment 2026-08-26 (#284 ruled, #288 built).* Paul's ruling: absorb,
+keep the data on what it costs us. The counters are no longer dormant:
+the usage sweep folds the hop subset into `backhaul_gb` and
+`backhaul_requests_1k`, which ride in every account statement as data;
+`RateCard.InterRegionGBUSD` prices the extra home→edge leg (the home
+box's metered bytes are already egress) as a model line on the
+economics page, in the model total and in NO account's cost, revenue or
+bill — `PriceAccount` ignores both meters, pinned by test. Read via the
+economics pages, `GET /api/economics/backhaul` and `carlos economics
+backhaul`.
+
*Rollout.* Must be rolled to every box of a deployment BEFORE that
deployment arms a second edge — the home box needs the new binary to
annotate hops, the senders need the cap. It slots ahead of the steering
diff --git a/economics.go b/economics.go
index 982362921..9c99ecb61 100644
--- a/economics.go
+++ b/economics.go
@@ -146,8 +146,9 @@ Shows what serving through region edges costs the platform this period:
the part of every account's egress that was backhauled from its home box
(usage.EdgeRow's hop subset — inside the egress totals, never on top),
priced at the rate card's inter-region $/GB (the extra leg; the home box's
-bytes are already egress) and ABSORBED — it is in nobody's bill (#284). Operator only; a non-operator's token gets the same bare 404
-an unknown route gets.
+bytes are already egress) and ABSORBED — it is in nobody's bill (#284).
+Operator only; a non-operator's token gets the same bare 404 an unknown
+route gets.
`
type backhaulReport struct {
@@ -218,19 +219,19 @@ func runEconomicsBackhaul(args []string) {
printBackhaulReport(stdout, rep)
}
-func printBackhaulReport(stdout io.Writer, rep backhaulReport) {
- fmt.Fprintf(stdout, "backhaul %s (%d/%d days covered): %.2f GB of %.2f GB egress (%.1f%%), %.1fk requests — inter-region leg ≈ $%.2f at $%.3f/GB, absorbed\n",
+func printBackhaulReport(w io.Writer, rep backhaulReport) {
+ fmt.Fprintf(w, "backhaul %s (%d/%d days covered): %.2f GB of %.2f GB egress (%.1f%%), %.1fk requests — inter-region leg ≈ $%.2f at $%.3f/GB, absorbed\n",
rep.Period, rep.CoveredDays, rep.PeriodDays, rep.BackhaulGB, rep.EgressGB, rep.ShareOfEgress*100, rep.BackhaulReq1k, rep.AbsorbedUSD, rep.InterRegionGBUSD)
if len(rep.Accounts) == 0 {
- fmt.Fprintln(stdout, "no account backhauled anything this period")
+ fmt.Fprintln(w, "no account backhauled anything this period")
return
}
- w := newTable(stdout)
- fmt.Fprintln(w, "ACCOUNT\tNAME\tEGRESS GB\tBACKHAUL GB\tSHARE\tREQ (k)\tABSORBED")
+ tw := newTable(w)
+ fmt.Fprintln(tw, "ACCOUNT\tNAME\tEGRESS GB\tBACKHAUL GB\tSHARE\tREQ (k)\tABSORBED")
for _, a := range rep.Accounts {
- fmt.Fprintf(w, "%s\t%s\t%.2f\t%.2f\t%.1f%%\t%.1f\t$%.2f\n", a.Account, a.Name, a.EgressGB, a.BackhaulGB, a.ShareOfEgress*100, a.BackhaulReq1k, a.AbsorbedUSD)
+ fmt.Fprintf(tw, "%s\t%s\t%.2f\t%.2f\t%.1f%%\t%.1f\t$%.2f\n", a.Account, a.Name, a.EgressGB, a.BackhaulGB, a.ShareOfEgress*100, a.BackhaulReq1k, a.AbsorbedUSD)
}
- w.Flush()
+ tw.Flush()
}
// economicsBillResult mirrors handleAPIEconomicsBill's success shape: the
diff --git a/internal/console/economicsbackhaul_test.go b/internal/console/economicsbackhaul_test.go
index e158d5a11..1f54633ff 100644
--- a/internal/console/economicsbackhaul_test.go
+++ b/internal/console/economicsbackhaul_test.go
@@ -106,4 +106,11 @@ func TestBackhaulMetersNeverPriceAnAccount(t *testing.T) {
if a != b {
t.Fatalf("backhaul meters changed an account's price:\n%+v\n%+v", a, b)
}
+ // And with nothing else metered: the meters must not even count as
+ // usage (FreeTierPos), the one generic meter walk PriceAccount has.
+ none := economics.PriceAccount(sc, "bab", map[string]float64{}, 0)
+ only := economics.PriceAccount(sc, "bab", map[string]float64{usage.MeterBackhaulGB: 25, usage.MeterBackhaulRequests1k: 500}, 0)
+ if none != only {
+ t.Fatalf("backhaul-only meters changed an otherwise idle account:\n%+v\n%+v", none, only)
+ }
}
diff --git a/internal/console/templates/economics.html b/internal/console/templates/economics.html
index 3cc92bd3c..ff3107a94 100644
--- a/internal/console/templates/economics.html
+++ b/internal/console/templates/economics.html
@@ -164,7 +164,8 @@
{{$s3storage := mul (sumMeter .Economics.Meters "storage_gb_month") .Economics.Scenario.RateCard.StorageGBMonthUSD}}
{{$s3requests := mul (sumMeter .Economics.Meters "requests_1k") .Economics.Scenario.RateCard.RequestsPer1kUSD}}
{{$egress := mul (sumMeter .Economics.Meters "egress_gb") .Economics.Scenario.RateCard.EgressGBUSD}}
-{{$backhaul := mul (sumMeter .Economics.Meters "backhaul_gb") .Economics.Scenario.RateCard.InterRegionGBUSD}}
+{{$backhaulGB := sumMeter .Economics.Meters "backhaul_gb"}}
+{{$backhaul := mul $backhaulGB .Economics.Scenario.RateCard.InterRegionGBUSD}}
{{$overheads := overheadUSD .Economics.Scenario .Economics.PeriodDays}}
{{$modelTotal := add $ec2 $ebs $s3storage $s3requests $egress $backhaul $overheads}}
<h2>Model vs. bill</h2>
@@ -176,8 +177,7 @@
<tr><td>S3 storage</td><td id="model-s3-storage">{{usd $s3storage}}</td></tr>
<tr><td>S3 requests</td><td id="model-s3-requests">{{usd $s3requests}}</td></tr>
<tr><td>Egress</td><td id="model-egress">{{usd $egress}}</td></tr>
- {{$backhaulGB := sumMeter .Economics.Meters "backhaul_gb"}}
- <tr><td>Backhaul (inter-region leg) <span class="small">{{printf "%.2f" $backhaulGB}} GB{{with sumMeter .Economics.Meters "egress_gb"}}{{if gt . 0.0}} · {{printf "%.1f" (mul (div $backhaulGB .) 100.0)}}% of egress{{end}}{{end}} · absorbed, in no account's bill</span></td><td id="model-backhaul">{{usd $backhaul}}</td></tr>
+ <tr><td>Backhaul (inter-region leg) <span class="small">{{printf "%.2f" $backhaulGB}} GB{{with sumMeter .Economics.Meters "egress_gb"}}{{if gt . 0.0}} · {{printf "%.1f" (mul (div $backhaulGB .) 100.0)}}% of egress{{end}}{{end}} · absorbed, in no account's bill{{if and (gt $backhaulGB 0.0) (eq .Economics.Scenario.RateCard.InterRegionGBUSD 0.0)}} · <strong>rate unset</strong> — set "Inter-region $/GB" in the knobs{{end}}</span></td><td id="model-backhaul">{{usd $backhaul}}</td></tr>
<tr><td>Overheads</td><td id="model-overheads">{{usd $overheads}}</td></tr>
<tr><th>Model total</th><th id="model-total">{{usd $modelTotal}}</th></tr>
</table>
@@ -711,7 +711,10 @@
if (revenue > 0) { margin = (revenue - cost) / revenue; }
var anyUsage = false;
- Object.keys(meters).forEach(function (k) { if (meters[k] > 0) { anyUsage = true; } });
+ Object.keys(meters).forEach(function (k) {
+ if (k === "backhaul_gb" || k === "backhaul_requests_1k") { return; } // data, not usage (#288)
+ if (meters[k] > 0) { anyUsage = true; }
+ });
var clipped = bEgress < (meters.egress_gb || 0) ||
bStorage < (meters.storage_gb_month || 0) ||
bApps < (meters.app_months || 0) ||
diff --git a/internal/economics/compute.go b/internal/economics/compute.go
index cf98f26a0..7ab9a1108 100644
--- a/internal/economics/compute.go
+++ b/internal/economics/compute.go
@@ -144,7 +144,13 @@ func PriceAccount(sc Scenario, account string, meters map[string]float64, alloca
}
anyUsage := false
- for _, v := range meters {
+ for k, v := range meters {
+ // The backhaul meters are data, not usage: a subset of egress,
+ // priced nowhere (#288). Skipped so that an account cannot look
+ // "inside the free tier" on their account alone.
+ if k == usage.MeterBackhaulGB || k == usage.MeterBackhaulRequests1k {
+ continue
+ }
if v > 0 {
anyUsage = true
break
diff --git a/internal/usage/usage.go b/internal/usage/usage.go
index 7a981a110..dd0ee44a9 100644
--- a/internal/usage/usage.go
+++ b/internal/usage/usage.go
@@ -28,8 +28,9 @@ const (
// reaching the client. It rides in statements and the economics sweep
// as data (#288) and is priced in NO account's cost, revenue or bill —
// #284's ruling is absorb. A billing engine iterating meters generically
- // must skip it; PriceAccount names its meters and does. The platform's
- // own cost for it is the inter-region leg, RateCard.InterRegionGBUSD.
+ // must skip it, as economics.PriceAccount's usage check does; its priced
+ // terms name their meters. The platform's own cost for it is the
+ // inter-region leg, RateCard.InterRegionGBUSD.
MeterBackhaulGB = "backhaul_gb"
// MeterBackhaulRequests1k is the request-count twin of MeterBackhaulGB:
// requests that crossed a region before being served. Informational,