Public: anyone can read this; the crew can change it.

The profit slider: one control per forge trading cost against responsiveness — placement, sleep windows, crew spend margin — with cost, revenue and the gap as board signal #513

Merged opened this in answer to

Check · Review · Land · Live done — Landed and live in production.

Merged

torque/forge:torque/392-the-profit-slider-one-control-per-forge → main 1 commit fork

  • Merged. torque/392-the-profit-slider-one-control-per-forge was merged into main as 505b2bf.

Review

Sign in to review this change.
1 file changed +85 −0
docs/PROFIT.md added +85
@@ -0,0 +1,85 @@
1 # The profit slider — cost against responsiveness
2
3 Design for issue #392, the twin of the subscription governor (#341): the
4 governor decides how much work runs now; the slider decides where it runs,
5 how long it stays awake, and what it is charged. Each forge has one slider.
6 It's built as linked issues; this page describes the design they share.
7
8 The owner wants owned metal to run at full capacity, because it is paid for
9 either way. Cloud takes the bursts. A forge charges for awake time, storage
10 and crew spend, with a margin on the crew spend.
11
12 ## The control
13
14 `position` is an integer from 0 to 100, set once for the whole forge:
15
16 - 0 is the cheapest setting: apps sleep early and nothing spills to cloud
17 until owned metal is full.
18 - 100 is the most responsive: apps stay warm and work spills to cloud early.
19
20 `policyAt(position)` is a pure function that interpolates linearly between
21 three anchor rows. Position 50 is today's behaviour exactly, so landing the
22 slider changes nothing until someone moves it.
23
24 | position | production sleeps after | preview sleeps after | idle pull stops after | cloud takes work above owned use |
25 | -------- | ----------------------- | -------------------- | --------------------- | -------------------------------- |
26 | 0 | 10 min | 5 min | 1 day | 100% (only when full) |
27 | 50 | 24 h | 30 min | 3 days | 85% |
28 | 100 | never | 24 h | never | 60% |
29
30 The 50 row is the constants in `src/apps/runtime.ts` (`SLEEP_AFTER_MS`) and
31 `FORGE_PREVIEW_IDLE_DAYS` in `src/main.ts`. "Never" counts as infinity in the
32 interpolation, so any position above 50 interpolates toward a cap of 7 days
33 instead. An app's `always_on: true` is the only override an app can set.
34
35 The margin is a separate number that sits next to the slider and does not
36 move with it. The margin sets price; the slider sets cost and
37 responsiveness. The board's gap line shows whether the two together leave a
38 profit.
39
40 ## Units and formulas
41
42 All money is in US dollars. Crew spend uses the list-price figure the usage
43 ledger already records (`src/core/usage.ts`).
44
45 - cost = owned box $/month, a fixed cost spread over the month
46 + cloud awake-hours × cloud $/hour
47 + GB-months × storage $/GB-month
48 + crew `costUsd`
49 - revenue = awake-hours × awake price
50 + GB-months × storage price
51 + crew `costUsd` × (1 + margin%)
52 - gap = revenue − cost
53
54 Rounding happens once, at the end, to the cent. Worked example: a $300 box,
55 40 h of cloud at $0.05, 12 GB-months at $0.02 and $57.10 of crew spend
56 cost $359.34.
57
58 ## The order (what waits for what)
59
60 | issue | what | waits for |
61 | ----- | ------------------------------------------------------------ | ---------- |
62 | #504 | the position, `policyAt`, Settings → Economics, the API | — |
63 | #505 | meter awake intervals and storage per app and environment | — |
64 | #506 | sleep windows follow the slider, live | #504 |
65 | #507 | cost model: owned amortised, cloud hourly, storage, crew | #504, #505 |
66 | #508 | revenue statement with the margin, JSON/CSV/print | #507 |
67 | #509 | placement policy: owned first, bursts spill | #504, #505 |
68 | #510 | the board: cost, revenue and the gap, with a 30-day SVG | #507, #508 |
69 | #511 | MCP `economics` read and its API twin | #510 |
70
71 #391 (the `services` app kind) waits for #509.
72
73 ## Choices
74
75 - The slider is one control per forge, not one per app. The only per-app
76 exception is `always_on`, and a `placement: metal|cloud` preference that
77 the policy honours unless owned capacity is full.
78 - Placement is decided here; where an app actually runs is up to the spawn
79 seam's body (`src/spawn/placement.ts`, spike #339). If no cloud body is
80 configured, the decision is always `owned`, and the board says that bursts
81 queue.
82 - The owned-node label (`plat.sh/site=vxrail` today) is a setting, not a
83 constant.
84 - Billing produces a statement, with no payment processor. A person can
85 check every line by hand.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs