Skip to content

Commit fd300d0

Browse files
ralyodioclaude
andauthored
pit: $2 a name, $5 an ending — no trailing cents (#144)
PRD 0005 §10.1 wrote these as $1.99 and $4.99. The extra cent buys nothing but a price tag shaped like a supermarket shelf, and every number here is one a person has to reason about: a default, a ceiling, a per-line override. Round. Which price is which mattered and was easy to get wrong. `moshpit_tlds .price_usd` sits on the ending's row but is the *child* price — what someone pays to mint `foo.bar`. Owning `.bar` means minting names under it for free; setting a price is how other people buy them. So $2 is the number that field carries, and the ending price is a separate thing. ENDING_PRICE_USD is defined and charged by nothing. `registerTld` inserts a row and claiming an ending is still free — the checkout that will read this needs terms and renewals first. It lives beside the child price anyway so the two are settled together, rather than being invented at the point someone builds that and reconciled afterwards. Still no enforcement on setTldPrice: a per-line `$5USD` is honoured. The ceiling is what the form defaults to and what the input hints at, not a rule the library imposes on an operator's own namespace. A test now fails on any price that is not whole dollars, so a regression to .99 cannot ship quietly. 263 across the pwa suite. Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
1 parent a57b608 commit fd300d0

3 files changed

Lines changed: 52 additions & 19 deletions

File tree

apps/pwa/src/lib/moshpit-name.mjs

Lines changed: 36 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -142,14 +142,39 @@ export function shortCount(n) {
142142
}
143143

144144
/**
145-
* The most a child name may cost per year.
145+
* The most a child name should cost per year.
146146
*
147-
* PRD 0005 §5 and §10.1, requirement R3: `me.whatever` is capped at $1.99/year.
148-
* An operator may go lower, including free. The cap is on the annual
149-
* registration/renewal price only — a one-time Buy Now resale is a transfer of
150-
* ownership, not a term, and §10.2.4 puts no ceiling on it.
147+
* This is the `me.whatever` price — what a buyer pays to mint a name under an
148+
* ending someone else holds. It is not the price of `.whatever` itself, which
149+
* is a separate thing the registry does not charge for yet.
150+
*
151+
* $2 flat. PRD 0005 R3 wrote this as $1.99; the extra cent buys nothing but a
152+
* price tag that looks like a supermarket shelf, and every number a person has
153+
* to reason about here — a default, a cap, a per-line override — reads better
154+
* round. The PRD number is superseded by this one.
155+
*
156+
* The ceiling is on the annual registration/renewal price only. A one-time
157+
* Buy Now resale transfers ownership rather than starting a term, and §10.2.4
158+
* puts no ceiling on that.
159+
*/
160+
export const MAX_CHILD_PRICE_USD = 2;
161+
162+
/** Alias, for code that reads better naming the thing than the ceiling. */
163+
export const CHILD_PRICE_USD = MAX_CHILD_PRICE_USD;
164+
165+
/**
166+
* What a direct ending costs per year: `.whatever` itself.
167+
*
168+
* Nothing charges this yet — `registerTld` inserts a row and claiming is free.
169+
* It lives here anyway so the two prices sit together and the number is settled
170+
* before the checkout that will read it, rather than being invented at the
171+
* point someone builds that and having to be reconciled afterwards.
172+
*
173+
* $5 flat, for the same reason the child price is $2: PRD 0005 §10.1 wrote
174+
* these as $4.99 and $1.99, and the trailing cents buy nothing but a price tag
175+
* shaped like a supermarket shelf.
151176
*/
152-
export const MAX_CHILD_PRICE_USD = 1.99;
177+
export const ENDING_PRICE_USD = 5;
153178

154179
/**
155180
* What names under a newly claimed ending cost unless you say otherwise.
@@ -158,13 +183,12 @@ export const MAX_CHILD_PRICE_USD = 1.99;
158183
* every buyer, and "I claimed forty and nobody could buy a name under any of
159184
* them" is the failure that costs something.
160185
*
161-
* $2 rather than MAX_CHILD_PRICE_USD: the cap in PRD 0005 R3 arrives with
162-
* terms and renewals, and until that lands this is an operator's asking price
163-
* with nothing enforcing a ceiling. A per-line price overrides this, upwards
164-
* or downwards, and clearing the field still means not for sale — the default
165-
* is an opinion, not a floor and not a limit.
186+
* The cap itself, not a number under it: $2 is already the round, memorable
187+
* price this namespace is meant to have, so there is nothing to shade off it
188+
* for. A per-line price overrides this in either direction, and clearing the
189+
* field still means not for sale — the default is an opinion, not a floor.
166190
*/
167-
export const DEFAULT_TLD_PRICE_USD = 2;
191+
export const DEFAULT_TLD_PRICE_USD = MAX_CHILD_PRICE_USD;
168192

169193
/**
170194
* Pull a list of endings out of whatever someone pasted.

apps/pwa/src/moshpit.mjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import { get, all, run } from "./db.mjs";
1414
import { BULK_TIME_BUDGET_MS, MAX_BULK_TLDS, MAX_CHILD_PRICE_USD, normalizeLabel, normalizeTld, parseMoshpitName, parseTldList, tldRejection } from "./lib/moshpit-name.mjs";
1515

1616
export {
17-
RESERVED_TLDS, RESOLVE_MODES, MAX_BULK_TLDS, BULK_TIME_BUDGET_MS, shortCount, DEFAULT_TLD_PRICE_USD, MAX_CHILD_PRICE_USD, normalizeLabel, normalizeTld, parseMoshpitName,
17+
RESERVED_TLDS, RESOLVE_MODES, MAX_BULK_TLDS, BULK_TIME_BUDGET_MS, shortCount, DEFAULT_TLD_PRICE_USD, MAX_CHILD_PRICE_USD, CHILD_PRICE_USD, ENDING_PRICE_USD, normalizeLabel, normalizeTld, parseMoshpitName,
1818
parseTldList, tldRejection, normalizeMode, resolutionPreference,
1919
} from "./lib/moshpit-name.mjs";
2020

apps/pwa/test/moshpit-bulk-claim.test.mjs

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -223,12 +223,21 @@ test("the default price", { skip: installed ? false : "pwa dependencies not inst
223223
const m = await import("../src/moshpit.mjs");
224224
const uniq = () => `d${randomBytes(4).toString("hex")}`;
225225

226-
await t.test("is $2, and nothing enforces a ceiling on an override", async () => {
227-
const { MAX_CHILD_PRICE_USD } = await import("../src/lib/moshpit-name.mjs");
228-
assert.equal(DEFAULT_TLD_PRICE_USD, 2);
229-
// PRD 0005 R3 caps a child name at $1.99, but that arrives with terms and
230-
// renewals; until then this is an asking price and a line may exceed it.
231-
assert.equal(MAX_CHILD_PRICE_USD, 1.99);
226+
await t.test("both prices are round, and neither ends in .99", async () => {
227+
const { CHILD_PRICE_USD, ENDING_PRICE_USD, MAX_CHILD_PRICE_USD } =
228+
await import("../src/lib/moshpit-name.mjs");
229+
230+
assert.equal(CHILD_PRICE_USD, 2, "foo.bar");
231+
assert.equal(ENDING_PRICE_USD, 5, ".bar");
232+
assert.equal(DEFAULT_TLD_PRICE_USD, CHILD_PRICE_USD);
233+
assert.equal(MAX_CHILD_PRICE_USD, CHILD_PRICE_USD);
234+
235+
// PRD 0005 §10.1 wrote these as $1.99 and $4.99. Superseded: the trailing
236+
// cent buys nothing and every number here is one a person has to reason
237+
// about. A regression to .99 should fail rather than ship quietly.
238+
for (const price of [CHILD_PRICE_USD, ENDING_PRICE_USD]) {
239+
assert.equal(price, Math.round(price), `${price} should be whole dollars`);
240+
}
232241
});
233242

234243
await t.test("an explicit price still wins over it", async () => {

0 commit comments

Comments
 (0)