Skip to content

Commit 8723f46

Browse files
committed
docs(costs): state the historical cache-write understatement, drop internal ids
Greptile flagged that the backfill prices pre-migration cache-creation tokens at the ordinary input rate. That is correct. Those tokens were summed into input_tokens and never stored separately, so the split is not recoverable and any correction would be a guessed ratio presented as data. Documented in the file header and surfaced at runtime with a count of affected rows, so the backfilled figure cannot be read as exact. cost_cents is unaffected. Also removes internal tracker ids from three comments, per CONTRIBUTING.
1 parent bfb068e commit 8723f46

3 files changed

Lines changed: 29 additions & 3 deletions

File tree

packages/db/src/backfill-cost-event-rate-card.ts

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* PHA-1626 backfill: populate `cost_events.rate_card_cents` and correct
2+
* Backfill: populate `cost_events.rate_card_cents` and correct
33
* `cost_events.cost_status` for rows written before the rate card existed.
44
*
55
* Historical rows carry correct token counts but were written with
@@ -23,6 +23,19 @@
2323
* tsx src/backfill-cost-event-rate-card.ts --apply # writes
2424
*
2525
* Idempotent: re-running recomputes the same values from the same tokens.
26+
*
27+
* KNOWN UNDERSTATEMENT on pre-migration rows. Before this change, cache-creation
28+
* tokens were summed into `input_tokens` and never stored separately, and the
29+
* migration defaults `cache_write_tokens` to 0. Those tokens are therefore
30+
* priced here at the ordinary input rate rather than the 1.25x cache-write
31+
* premium, so historical `rate_card_cents` is slightly low.
32+
*
33+
* This is not recoverable: the split was never recorded, and any correction
34+
* would be a guessed ratio dressed up as data. A rate card that is slightly low
35+
* and honest about it beats one that is invented. Rows written after this change
36+
* carry a real `cache_write_tokens` and are priced exactly. The affected span is
37+
* bounded and shrinking, and the figure is notional in the first place — it
38+
* never reaches `cost_cents`, so nothing downstream of cash is affected.
2639
*/
2740
import { deriveRateCardCents } from "@paperclipai/shared";
2841
import postgres from "postgres";
@@ -120,11 +133,24 @@ async function main(): Promise<void> {
120133
if (!unchanged) updates.push({ id: row.id, resolution });
121134
}
122135

136+
const foldedCacheWriteRows = rows.filter(
137+
(row) => Number(row.cache_write_tokens) === 0 && Number(row.input_tokens) > 0,
138+
).length;
139+
123140
console.log(`Scanned ${rows.length} cost_events row(s).`);
124141
for (const [status, tally] of [...byStatus.entries()].sort((a, b) => b[1].rows - a[1].rows)) {
125142
console.log(` ${status.padEnd(9)} ${String(tally.rows).padStart(6)} rows rate card $${(tally.cents / 100).toFixed(2)}`);
126143
}
127144
console.log(`${updates.length} row(s) need updating.`);
145+
if (foldedCacheWriteRows > 0) {
146+
console.log(
147+
`Note: ${foldedCacheWriteRows} row(s) have cache_write_tokens=0 with non-zero input_tokens. ` +
148+
"Rows written before cache writes were recorded separately fold those tokens into " +
149+
"input_tokens, so they are priced at the input rate rather than the 1.25x cache-write " +
150+
"premium. Their rate card is therefore a slight underestimate. This is not recoverable " +
151+
"from stored data. cost_cents is unaffected.",
152+
);
153+
}
128154

129155
if (!apply) {
130156
console.log("Dry run. Re-run with --apply to write.");

packages/shared/src/model-rate-card.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ describe("deriveRateCardCents", () => {
111111
});
112112

113113
it("prices a realistic subscription run that the CLI reported as $0", () => {
114-
// The PHA-1626 shape: hundreds of millions of tokens booked at zero cash.
114+
// The bug this guards: hundreds of millions of tokens booked at zero cash.
115115
const derived = deriveRateCardCents("claude-opus-4-8", {
116116
inputTokens: 2_732_577,
117117
cachedInputTokens: 2_632_998,

server/src/__tests__/heartbeat-cost-accounting.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ describe("heartbeat cost accounting", () => {
6666
})).toBe("derived");
6767
});
6868

69-
// The PHA-1626 invariant. Subscription CLIs emit a numeric 0 rather than
69+
// The core invariant. Subscription CLIs emit a numeric 0 rather than
7070
// null, which used to fall through to "reported" and made hundreds of
7171
// millions of real tokens indistinguishable from genuinely free work.
7272
describe("nonzero tokens with a $0 reported cost can never be 'reported'", () => {

0 commit comments

Comments
 (0)