instar 1.3.781 → 1.3.783
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/core/IntelligenceRouter.d.ts +9 -14
- package/dist/core/IntelligenceRouter.d.ts.map +1 -1
- package/dist/core/IntelligenceRouter.js +117 -56
- package/dist/core/IntelligenceRouter.js.map +1 -1
- package/dist/core/MeteredSpendGate.d.ts +119 -0
- package/dist/core/MeteredSpendGate.d.ts.map +1 -0
- package/dist/core/MeteredSpendGate.js +228 -0
- package/dist/core/MeteredSpendGate.js.map +1 -0
- package/dist/core/MeteredSpendLedger.d.ts +154 -0
- package/dist/core/MeteredSpendLedger.d.ts.map +1 -0
- package/dist/core/MeteredSpendLedger.js +434 -0
- package/dist/core/MeteredSpendLedger.js.map +1 -0
- package/dist/core/PinAttemptStore.d.ts +35 -0
- package/dist/core/PinAttemptStore.d.ts.map +1 -0
- package/dist/core/PinAttemptStore.js +85 -0
- package/dist/core/PinAttemptStore.js.map +1 -0
- package/dist/core/PostUpdateMigrator.d.ts +7 -0
- package/dist/core/PostUpdateMigrator.d.ts.map +1 -1
- package/dist/core/PostUpdateMigrator.js +24 -0
- package/dist/core/PostUpdateMigrator.js.map +1 -1
- package/dist/core/RenderedPlanStore.d.ts +61 -0
- package/dist/core/RenderedPlanStore.d.ts.map +1 -0
- package/dist/core/RenderedPlanStore.js +92 -0
- package/dist/core/RenderedPlanStore.js.map +1 -0
- package/dist/core/RoutingSpendCapsStore.d.ts +113 -0
- package/dist/core/RoutingSpendCapsStore.d.ts.map +1 -0
- package/dist/core/RoutingSpendCapsStore.js +241 -0
- package/dist/core/RoutingSpendCapsStore.js.map +1 -0
- package/dist/core/SpendAlertResolver.d.ts +77 -0
- package/dist/core/SpendAlertResolver.d.ts.map +1 -0
- package/dist/core/SpendAlertResolver.js +141 -0
- package/dist/core/SpendAlertResolver.js.map +1 -0
- package/dist/core/WriteDomainRegistry.d.ts.map +1 -1
- package/dist/core/WriteDomainRegistry.js +17 -0
- package/dist/core/WriteDomainRegistry.js.map +1 -1
- package/dist/core/devGatedFeatures.d.ts.map +1 -1
- package/dist/core/devGatedFeatures.js +9 -0
- package/dist/core/devGatedFeatures.js.map +1 -1
- package/dist/core/routingSpendView.d.ts +10 -2
- package/dist/core/routingSpendView.d.ts.map +1 -1
- package/dist/core/routingSpendView.js +18 -10
- package/dist/core/routingSpendView.js.map +1 -1
- package/dist/core/types.d.ts +24 -2
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js.map +1 -1
- package/dist/server/AgentServer.d.ts +9 -0
- package/dist/server/AgentServer.d.ts.map +1 -1
- package/dist/server/AgentServer.js +177 -0
- package/dist/server/AgentServer.js.map +1 -1
- package/dist/server/routes.d.ts +10 -0
- package/dist/server/routes.d.ts.map +1 -1
- package/dist/server/routes.js +196 -4
- package/dist/server/routes.js.map +1 -1
- package/dist/testing/selfActionRegistry.d.ts.map +1 -1
- package/dist/testing/selfActionRegistry.js +78 -0
- package/dist/testing/selfActionRegistry.js.map +1 -1
- package/package.json +1 -1
- package/src/data/builtin-manifest.json +64 -64
- package/upgrades/1.3.782.md +60 -0
- package/upgrades/1.3.783.md +66 -0
- package/upgrades/nature-routing-a2.2-enforcing.eli16.md +50 -0
- package/upgrades/side-effects/nature-routing-a2.2-enforcing.md +142 -0
- package/upgrades/side-effects/routing-spend-increment-b.md +44 -0
|
@@ -0,0 +1,434 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MeteredSpendLedger — Layer 3 of the Routing Control Room
|
|
3
|
+
* (docs/specs/routing-control-room-spend-alerts.md, Increment B).
|
|
4
|
+
*
|
|
5
|
+
* The AUTHORITATIVE money truth: an append-only, booking-priced ledger of every
|
|
6
|
+
* metered-door reservation/settlement, plus a maintained O(1) committed total the
|
|
7
|
+
* fail-closed gate reads. This ledger — NOT `feature_metrics`, NOT the Layer-1c
|
|
8
|
+
* provider-report store — is the ONLY rebuild source for committed spend
|
|
9
|
+
* (FD-3/FD-9): rebuilding from Layer 0 joined to current prices is FORBIDDEN at
|
|
10
|
+
* the gate (a downward `corrects` would re-open capped headroom).
|
|
11
|
+
*
|
|
12
|
+
* Write discipline (adopted from DriftSpendLedger, upgraded per spec C4-2):
|
|
13
|
+
* - Rows are APPEND-ONLY JSONL, fsync'd, written FIRST; the totals file is a
|
|
14
|
+
* regenerable CACHE of the fold, rewritten atomically (tmp+rename) SECOND.
|
|
15
|
+
* A crash between the two leaves totals STALE-LOW by at most one booking; the
|
|
16
|
+
* next gate read runs a cheap high-water check (file size) and re-folds.
|
|
17
|
+
* - Writes are FAIL-CLOSED and NON-SWALLOWING: a booking that cannot be durably
|
|
18
|
+
* persisted throws, and the caller must refuse the metered call.
|
|
19
|
+
* - Boot: fold all rows, REWRITE the totals cache from row truth (torn totals
|
|
20
|
+
* rename / totals-without-append are always corrected; the append-first
|
|
21
|
+
* ordering makes totals-without-append impossible, asserted in tests).
|
|
22
|
+
* - A torn trailing append (partial last line) is the malformed-row-skip case.
|
|
23
|
+
*
|
|
24
|
+
* Reserve/settle lifecycle (A-B2/A2-1):
|
|
25
|
+
* - reserve(): books the worst-case estimate (cached tokens as FULL input,
|
|
26
|
+
* FD-19; output at the REQUIRED max-tokens ceiling). Outstanding reserves are
|
|
27
|
+
* INSIDE the committed total (concurrent reservations see each other).
|
|
28
|
+
* - settle(): idempotent terminal `reserved → settled`; books ACTUAL cost.
|
|
29
|
+
* A settle after expiry books the actual cost as a fresh ABSOLUTE row
|
|
30
|
+
* (expiry-aware settle) — the late-settle race can never under-count.
|
|
31
|
+
* - expire(): the reserve-expiry sweep (takes the per-key mutex) expires only
|
|
32
|
+
* reserves older than the TTL still in `reserved` state.
|
|
33
|
+
* - First terminal transition wins; the loser is a no-op.
|
|
34
|
+
*
|
|
35
|
+
* Concurrency: metered calls funnel through the single server process, so the
|
|
36
|
+
* booking critical sections are guarded by an in-process async mutex per keyRef
|
|
37
|
+
* (held only for the booking, RELEASED during the LLM round-trip) plus a
|
|
38
|
+
* proper-lockfile advisory lock for defence against a second process.
|
|
39
|
+
*/
|
|
40
|
+
import fs from 'node:fs';
|
|
41
|
+
import path from 'node:path';
|
|
42
|
+
import crypto from 'node:crypto';
|
|
43
|
+
import lockfile from 'proper-lockfile';
|
|
44
|
+
const LOCK_OPTIONS = {
|
|
45
|
+
retries: { retries: 50, factor: 1.2, minTimeout: 50, maxTimeout: 500 },
|
|
46
|
+
stale: 10_000,
|
|
47
|
+
realpath: false,
|
|
48
|
+
};
|
|
49
|
+
/** Default reserve TTL — pinned comfortably above the metered-call latency ceiling (spec: 15 min vs a 5-min call ceiling). */
|
|
50
|
+
export const DEFAULT_RESERVE_TTL_MS = 15 * 60 * 1000;
|
|
51
|
+
/** Thrown by reserve() when admitOnlyUnderCaps would be breached — nothing was booked. */
|
|
52
|
+
export class CapExceededError extends Error {
|
|
53
|
+
capKind;
|
|
54
|
+
committedUsd;
|
|
55
|
+
reserveUsd;
|
|
56
|
+
capUsd;
|
|
57
|
+
constructor(capKind, committedUsd, reserveUsd, capUsd) {
|
|
58
|
+
super(`${capKind}: committed ${committedUsd.toFixed(4)} + reserve ${reserveUsd.toFixed(4)} > cap ${capUsd.toFixed(2)}`);
|
|
59
|
+
this.capKind = capKind;
|
|
60
|
+
this.committedUsd = committedUsd;
|
|
61
|
+
this.reserveUsd = reserveUsd;
|
|
62
|
+
this.capUsd = capUsd;
|
|
63
|
+
this.name = 'CapExceededError';
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
export class MeteredLedgerWriteError extends Error {
|
|
67
|
+
cause;
|
|
68
|
+
constructor(msg, cause) {
|
|
69
|
+
super(`metered-spend ledger write failed (fail-closed): ${msg}`);
|
|
70
|
+
this.cause = cause;
|
|
71
|
+
this.name = 'MeteredLedgerWriteError';
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
function utcDay(ms) {
|
|
75
|
+
return new Date(ms).toISOString().slice(0, 10);
|
|
76
|
+
}
|
|
77
|
+
function round6(n) {
|
|
78
|
+
return Math.round(n * 1e6) / 1e6;
|
|
79
|
+
}
|
|
80
|
+
export class MeteredSpendLedger {
|
|
81
|
+
rowsPath;
|
|
82
|
+
totalsPath;
|
|
83
|
+
lockTarget;
|
|
84
|
+
ttlMs;
|
|
85
|
+
now;
|
|
86
|
+
/** In-memory fold state, authoritative in-process. Rebuilt on construction. */
|
|
87
|
+
reserves = new Map();
|
|
88
|
+
totals = new Map();
|
|
89
|
+
/** Byte length of the rows file as of our last append/fold (the high-water mark). */
|
|
90
|
+
rowsBytes = 0;
|
|
91
|
+
/** In-process per-key mutex tail. */
|
|
92
|
+
mutexTail = new Map();
|
|
93
|
+
constructor(opts) {
|
|
94
|
+
const stateSub = path.join(opts.stateDir, 'state');
|
|
95
|
+
const localSub = path.join(opts.stateDir, 'local');
|
|
96
|
+
fs.mkdirSync(stateSub, { recursive: true });
|
|
97
|
+
fs.mkdirSync(localSub, { recursive: true });
|
|
98
|
+
this.rowsPath = path.join(stateSub, 'metered-spend-ledger.jsonl');
|
|
99
|
+
this.totalsPath = path.join(stateSub, 'metered-spend-totals.json');
|
|
100
|
+
this.lockTarget = path.join(localSub, 'metered-spend.lock');
|
|
101
|
+
if (!fs.existsSync(this.lockTarget))
|
|
102
|
+
fs.writeFileSync(this.lockTarget, '');
|
|
103
|
+
this.ttlMs = opts.reserveTtlMs ?? DEFAULT_RESERVE_TTL_MS;
|
|
104
|
+
this.now = opts.now ?? (() => Date.now());
|
|
105
|
+
// Boot: the fold is canon — rebuild from rows and REWRITE the totals cache.
|
|
106
|
+
this.refoldFromRows();
|
|
107
|
+
this.rewriteTotalsCache();
|
|
108
|
+
}
|
|
109
|
+
// ── Public API ─────────────────────────────────────────────────────
|
|
110
|
+
/** O(1) committed totals for a key, day-rolled to NOW. High-water-checked against external appends. */
|
|
111
|
+
committed(keyRef) {
|
|
112
|
+
this.checkHighWater();
|
|
113
|
+
return this.currentTotals(keyRef);
|
|
114
|
+
}
|
|
115
|
+
/** Reserve worst-case cost. FAIL-CLOSED: any persistence failure throws. */
|
|
116
|
+
async reserve(req) {
|
|
117
|
+
if (!Number.isFinite(req.reserveUsd) || req.reserveUsd < 0) {
|
|
118
|
+
throw new MeteredLedgerWriteError(`invalid reserveUsd ${req.reserveUsd}`);
|
|
119
|
+
}
|
|
120
|
+
return this.withKeyMutex(req.keyRef, async () => {
|
|
121
|
+
this.checkHighWater();
|
|
122
|
+
if (req.admitOnlyUnderCaps) {
|
|
123
|
+
// ATOMIC check-and-reserve: this runs inside the per-key mutex, so every
|
|
124
|
+
// outstanding concurrent reservation is already in the committed total.
|
|
125
|
+
const t = this.currentTotals(req.keyRef);
|
|
126
|
+
if (t.committedLifetimeUsd + req.reserveUsd > req.admitOnlyUnderCaps.lifetimeCapUsd) {
|
|
127
|
+
throw new CapExceededError('lifetime', t.committedLifetimeUsd, req.reserveUsd, req.admitOnlyUnderCaps.lifetimeCapUsd);
|
|
128
|
+
}
|
|
129
|
+
if (t.committedDayUsd + req.reserveUsd > req.admitOnlyUnderCaps.dailyCapUsd) {
|
|
130
|
+
throw new CapExceededError('daily', t.committedDayUsd, req.reserveUsd, req.admitOnlyUnderCaps.dailyCapUsd);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
const nowMs = this.now();
|
|
134
|
+
const reserveId = crypto.randomBytes(12).toString('hex');
|
|
135
|
+
const row = {
|
|
136
|
+
ts: new Date(nowMs).toISOString(),
|
|
137
|
+
keyRef: req.keyRef,
|
|
138
|
+
door: req.door,
|
|
139
|
+
modelId: req.modelId,
|
|
140
|
+
kind: 'reserve',
|
|
141
|
+
reserveId,
|
|
142
|
+
costUsd: round6(req.reserveUsd),
|
|
143
|
+
leaseEpoch: req.leaseEpoch,
|
|
144
|
+
};
|
|
145
|
+
await this.appendDurable(row);
|
|
146
|
+
this.applyRow(row);
|
|
147
|
+
this.rewriteTotalsCache();
|
|
148
|
+
const t = this.currentTotals(req.keyRef);
|
|
149
|
+
return { reserveId, committedLifetimeUsd: t.committedLifetimeUsd, committedDayUsd: t.committedDayUsd };
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Terminal settle at ACTUAL cost. Idempotent: a second settle is a no-op.
|
|
154
|
+
* A settle after expiry books the actual as a fresh ABSOLUTE row (late-settle).
|
|
155
|
+
*/
|
|
156
|
+
async settle(keyRef, reserveId, actualUsd) {
|
|
157
|
+
if (!Number.isFinite(actualUsd) || actualUsd < 0) {
|
|
158
|
+
throw new MeteredLedgerWriteError(`invalid actualUsd ${actualUsd}`);
|
|
159
|
+
}
|
|
160
|
+
return this.withKeyMutex(keyRef, async () => {
|
|
161
|
+
const st = this.reserves.get(reserveId);
|
|
162
|
+
if (st && st.state === 'settled')
|
|
163
|
+
return; // first terminal wins — no-op
|
|
164
|
+
const lateAfterExpire = st?.state === 'expired';
|
|
165
|
+
const row = {
|
|
166
|
+
ts: new Date(this.now()).toISOString(),
|
|
167
|
+
keyRef,
|
|
168
|
+
door: st?.door ?? 'unknown',
|
|
169
|
+
modelId: st?.modelId ?? 'unknown',
|
|
170
|
+
kind: 'settle',
|
|
171
|
+
reserveId,
|
|
172
|
+
costUsd: round6(actualUsd),
|
|
173
|
+
leaseEpoch: 0,
|
|
174
|
+
...(lateAfterExpire ? { lateAfterExpire: true } : {}),
|
|
175
|
+
};
|
|
176
|
+
await this.appendDurable(row);
|
|
177
|
+
this.applyRow(row);
|
|
178
|
+
this.rewriteTotalsCache();
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
/** Reserve-expiry sweep (Layer 3 — takes the per-key mutex). Expires only TTL-stale `reserved` states. */
|
|
182
|
+
async sweepExpired() {
|
|
183
|
+
const nowMs = this.now();
|
|
184
|
+
let expired = 0;
|
|
185
|
+
// Group stale reserves by key so each key's bookings stay serialized.
|
|
186
|
+
const byKey = new Map();
|
|
187
|
+
for (const [id, st] of this.reserves) {
|
|
188
|
+
if (st.state !== 'reserved')
|
|
189
|
+
continue;
|
|
190
|
+
if (nowMs - st.reservedAtMs <= this.ttlMs)
|
|
191
|
+
continue;
|
|
192
|
+
const arr = byKey.get(st.keyRef) ?? [];
|
|
193
|
+
arr.push({ id, st });
|
|
194
|
+
byKey.set(st.keyRef, arr);
|
|
195
|
+
}
|
|
196
|
+
for (const [keyRef, stales] of byKey) {
|
|
197
|
+
await this.withKeyMutex(keyRef, async () => {
|
|
198
|
+
for (const { id, st } of stales) {
|
|
199
|
+
if (st.state !== 'reserved')
|
|
200
|
+
continue; // settled while we waited — first terminal wins
|
|
201
|
+
const row = {
|
|
202
|
+
ts: new Date(this.now()).toISOString(),
|
|
203
|
+
keyRef,
|
|
204
|
+
door: st.door,
|
|
205
|
+
modelId: st.modelId,
|
|
206
|
+
kind: 'expire',
|
|
207
|
+
reserveId: id,
|
|
208
|
+
costUsd: 0,
|
|
209
|
+
leaseEpoch: 0,
|
|
210
|
+
};
|
|
211
|
+
await this.appendDurable(row);
|
|
212
|
+
this.applyRow(row);
|
|
213
|
+
expired++;
|
|
214
|
+
}
|
|
215
|
+
this.rewriteTotalsCache();
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
return expired;
|
|
219
|
+
}
|
|
220
|
+
/** All totals (for the caps view). Day-rolled to now. */
|
|
221
|
+
allCommitted() {
|
|
222
|
+
this.checkHighWater();
|
|
223
|
+
const keys = new Set();
|
|
224
|
+
for (const st of this.reserves.values())
|
|
225
|
+
keys.add(st.keyRef);
|
|
226
|
+
for (const k of this.totals.keys())
|
|
227
|
+
keys.add(k);
|
|
228
|
+
return [...keys].map((k) => this.currentTotals(k));
|
|
229
|
+
}
|
|
230
|
+
// ── Fold internals ─────────────────────────────────────────────────
|
|
231
|
+
/** Apply one row to the in-memory fold. */
|
|
232
|
+
applyRow(row, opts) {
|
|
233
|
+
const day = utcDay(Date.parse(row.ts));
|
|
234
|
+
if (row.kind === 'reserve') {
|
|
235
|
+
this.reserves.set(row.reserveId, {
|
|
236
|
+
keyRef: row.keyRef,
|
|
237
|
+
door: row.door,
|
|
238
|
+
modelId: row.modelId,
|
|
239
|
+
reserveUsd: row.costUsd,
|
|
240
|
+
day,
|
|
241
|
+
reservedAtMs: Date.parse(row.ts),
|
|
242
|
+
state: 'reserved',
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
else if (row.kind === 'settle') {
|
|
246
|
+
const st = this.reserves.get(row.reserveId);
|
|
247
|
+
if (st) {
|
|
248
|
+
if (st.state === 'settled')
|
|
249
|
+
return; // idempotent
|
|
250
|
+
st.state = 'settled';
|
|
251
|
+
st.settledUsd = row.costUsd;
|
|
252
|
+
// A late settle books on the SETTLE's own day when the reserve day already
|
|
253
|
+
// contributed nothing (it was expired); otherwise the contribution keeps
|
|
254
|
+
// the reserve's day.
|
|
255
|
+
if (row.lateAfterExpire)
|
|
256
|
+
st.day = day;
|
|
257
|
+
}
|
|
258
|
+
else {
|
|
259
|
+
// Settle with no known reserve (e.g. rows pruned): book absolute on its own day.
|
|
260
|
+
this.reserves.set(row.reserveId, {
|
|
261
|
+
keyRef: row.keyRef,
|
|
262
|
+
door: row.door,
|
|
263
|
+
modelId: row.modelId,
|
|
264
|
+
reserveUsd: 0,
|
|
265
|
+
day,
|
|
266
|
+
reservedAtMs: Date.parse(row.ts),
|
|
267
|
+
state: 'settled',
|
|
268
|
+
settledUsd: row.costUsd,
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
else if (row.kind === 'expire') {
|
|
273
|
+
const st = this.reserves.get(row.reserveId);
|
|
274
|
+
if (st && st.state === 'reserved')
|
|
275
|
+
st.state = 'expired';
|
|
276
|
+
}
|
|
277
|
+
if (!opts?.skipTotals)
|
|
278
|
+
this.recomputeTotalsForKey(row.keyRef);
|
|
279
|
+
}
|
|
280
|
+
/** Contribution of one reserve state to committed totals. */
|
|
281
|
+
contribution(st) {
|
|
282
|
+
if (st.state === 'settled')
|
|
283
|
+
return st.settledUsd ?? 0;
|
|
284
|
+
if (st.state === 'expired')
|
|
285
|
+
return 0;
|
|
286
|
+
return st.reserveUsd; // outstanding reserve — inside the committed total
|
|
287
|
+
}
|
|
288
|
+
recomputeTotalsForKey(keyRef) {
|
|
289
|
+
const today = utcDay(this.now());
|
|
290
|
+
let lifetime = 0;
|
|
291
|
+
let dayUsd = 0;
|
|
292
|
+
for (const st of this.reserves.values()) {
|
|
293
|
+
if (st.keyRef !== keyRef)
|
|
294
|
+
continue;
|
|
295
|
+
const c = this.contribution(st);
|
|
296
|
+
lifetime += c;
|
|
297
|
+
if (st.day === today)
|
|
298
|
+
dayUsd += c;
|
|
299
|
+
}
|
|
300
|
+
this.totals.set(keyRef, {
|
|
301
|
+
keyRef,
|
|
302
|
+
committedLifetimeUsd: round6(lifetime),
|
|
303
|
+
committedDayUsd: round6(dayUsd),
|
|
304
|
+
dayEpoch: today,
|
|
305
|
+
updatedAt: new Date(this.now()).toISOString(),
|
|
306
|
+
});
|
|
307
|
+
}
|
|
308
|
+
/** Day-rolled view of a key's totals (a new UTC day resets the day figure). */
|
|
309
|
+
currentTotals(keyRef) {
|
|
310
|
+
const today = utcDay(this.now());
|
|
311
|
+
const t = this.totals.get(keyRef);
|
|
312
|
+
if (!t) {
|
|
313
|
+
return { keyRef, committedLifetimeUsd: 0, committedDayUsd: 0, dayEpoch: today, updatedAt: new Date(this.now()).toISOString() };
|
|
314
|
+
}
|
|
315
|
+
if (t.dayEpoch !== today) {
|
|
316
|
+
this.recomputeTotalsForKey(keyRef);
|
|
317
|
+
return this.totals.get(keyRef);
|
|
318
|
+
}
|
|
319
|
+
return t;
|
|
320
|
+
}
|
|
321
|
+
/** Full refold from row truth (the fold is canon; the totals file is a cache). */
|
|
322
|
+
refoldFromRows() {
|
|
323
|
+
this.reserves = new Map();
|
|
324
|
+
this.totals = new Map();
|
|
325
|
+
let raw = '';
|
|
326
|
+
try {
|
|
327
|
+
raw = fs.readFileSync(this.rowsPath, 'utf-8');
|
|
328
|
+
this.rowsBytes = Buffer.byteLength(raw);
|
|
329
|
+
}
|
|
330
|
+
catch {
|
|
331
|
+
// @silent-fallback-ok: no rows file yet — a fresh ledger folds to zero.
|
|
332
|
+
this.rowsBytes = 0;
|
|
333
|
+
return;
|
|
334
|
+
}
|
|
335
|
+
const keys = new Set();
|
|
336
|
+
for (const line of raw.split('\n')) {
|
|
337
|
+
if (!line.trim())
|
|
338
|
+
continue;
|
|
339
|
+
let row;
|
|
340
|
+
try {
|
|
341
|
+
row = JSON.parse(line);
|
|
342
|
+
}
|
|
343
|
+
catch {
|
|
344
|
+
// Malformed-row-skip: a torn trailing append is expected crash residue.
|
|
345
|
+
continue;
|
|
346
|
+
}
|
|
347
|
+
if (typeof row?.reserveId !== 'string' ||
|
|
348
|
+
typeof row?.keyRef !== 'string' ||
|
|
349
|
+
typeof row?.costUsd !== 'number' ||
|
|
350
|
+
!Number.isFinite(row.costUsd) ||
|
|
351
|
+
row.costUsd < 0 ||
|
|
352
|
+
!['reserve', 'settle', 'expire'].includes(row?.kind)) {
|
|
353
|
+
continue;
|
|
354
|
+
}
|
|
355
|
+
// Inline apply without per-row totals recompute (batched below).
|
|
356
|
+
keys.add(row.keyRef);
|
|
357
|
+
this.applyRow(row, { skipTotals: true });
|
|
358
|
+
}
|
|
359
|
+
for (const k of keys)
|
|
360
|
+
this.recomputeTotalsForKey(k);
|
|
361
|
+
}
|
|
362
|
+
/** Cheap external-append detection: rows-file byte length vs our high-water mark. */
|
|
363
|
+
checkHighWater() {
|
|
364
|
+
let size = 0;
|
|
365
|
+
try {
|
|
366
|
+
size = fs.statSync(this.rowsPath).size;
|
|
367
|
+
}
|
|
368
|
+
catch {
|
|
369
|
+
// @silent-fallback-ok: rows file absent — nothing appended externally.
|
|
370
|
+
size = 0;
|
|
371
|
+
}
|
|
372
|
+
if (size !== this.rowsBytes) {
|
|
373
|
+
this.refoldFromRows();
|
|
374
|
+
this.rewriteTotalsCache();
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
// ── Durable write internals ────────────────────────────────────────
|
|
378
|
+
/** Append one row, fsync'd, under the advisory file lock. NON-SWALLOWING. */
|
|
379
|
+
async appendDurable(row) {
|
|
380
|
+
let release = null;
|
|
381
|
+
try {
|
|
382
|
+
release = await lockfile.lock(this.lockTarget, LOCK_OPTIONS);
|
|
383
|
+
const line = JSON.stringify(row) + '\n';
|
|
384
|
+
const fd = fs.openSync(this.rowsPath, 'a', 0o600);
|
|
385
|
+
try {
|
|
386
|
+
fs.writeSync(fd, line);
|
|
387
|
+
fs.fsyncSync(fd);
|
|
388
|
+
}
|
|
389
|
+
finally {
|
|
390
|
+
fs.closeSync(fd);
|
|
391
|
+
}
|
|
392
|
+
this.rowsBytes += Buffer.byteLength(line);
|
|
393
|
+
}
|
|
394
|
+
catch (err) {
|
|
395
|
+
throw new MeteredLedgerWriteError(String(err), err);
|
|
396
|
+
}
|
|
397
|
+
finally {
|
|
398
|
+
if (release)
|
|
399
|
+
await release().catch(() => { });
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
/** Atomic (tmp+rename) rewrite of the totals cache. Best-effort — rows are canon. */
|
|
403
|
+
rewriteTotalsCache() {
|
|
404
|
+
try {
|
|
405
|
+
const file = { rowsBytes: this.rowsBytes, totals: Object.fromEntries(this.totals) };
|
|
406
|
+
const tmp = this.totalsPath + '.tmp';
|
|
407
|
+
fs.writeFileSync(tmp, JSON.stringify(file, null, 2), { mode: 0o600 });
|
|
408
|
+
fs.renameSync(tmp, this.totalsPath);
|
|
409
|
+
}
|
|
410
|
+
catch {
|
|
411
|
+
// @silent-fallback-ok: the totals file is a regenerable CACHE of the fold —
|
|
412
|
+
// a failed cache write never blocks a booking (rows are already durable) and
|
|
413
|
+
// is corrected by the next boot-time refold.
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
// ── In-process per-key mutex ───────────────────────────────────────
|
|
417
|
+
withKeyMutex(keyRef, fn) {
|
|
418
|
+
const tail = this.mutexTail.get(keyRef) ?? Promise.resolve();
|
|
419
|
+
let done;
|
|
420
|
+
const next = new Promise((r) => (done = r));
|
|
421
|
+
this.mutexTail.set(keyRef, next);
|
|
422
|
+
return tail.then(async () => {
|
|
423
|
+
try {
|
|
424
|
+
return await fn();
|
|
425
|
+
}
|
|
426
|
+
finally {
|
|
427
|
+
done();
|
|
428
|
+
if (this.mutexTail.get(keyRef) === next)
|
|
429
|
+
this.mutexTail.delete(keyRef);
|
|
430
|
+
}
|
|
431
|
+
});
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
//# sourceMappingURL=MeteredSpendLedger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MeteredSpendLedger.js","sourceRoot":"","sources":["../../src/core/MeteredSpendLedger.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PinAttemptStore — durable write-through behind the PIN routes' per-IP
|
|
3
|
+
* brute-force lockout (docs/specs/routing-control-room-spend-alerts.md,
|
|
4
|
+
* Surface 2, S2-1 hardening).
|
|
5
|
+
*
|
|
6
|
+
* `checkMandatePin`'s attempt counter was an in-memory Map, so a server restart
|
|
7
|
+
* reset the lockout. This store persists the counters to
|
|
8
|
+
* `<stateDir>/state/pin-attempts.json` (atomic tmp+rename) and is shared by the
|
|
9
|
+
* PIN routes. Semantics unchanged: N attempts per window per IP; the window
|
|
10
|
+
* expiry clears the entry. Express `trust proxy` is off fleet-wide, so req.ip
|
|
11
|
+
* already ignores X-Forwarded-For.
|
|
12
|
+
*/
|
|
13
|
+
export declare class PinAttemptStore {
|
|
14
|
+
private readonly filePath;
|
|
15
|
+
private entries;
|
|
16
|
+
private readonly maxAttempts;
|
|
17
|
+
private readonly windowMs;
|
|
18
|
+
private readonly now;
|
|
19
|
+
constructor(opts: {
|
|
20
|
+
stateDir: string;
|
|
21
|
+
maxAttempts?: number;
|
|
22
|
+
windowMs?: number;
|
|
23
|
+
now?: () => number;
|
|
24
|
+
});
|
|
25
|
+
/** True when the IP is currently locked out. */
|
|
26
|
+
blocked(ip: string): boolean;
|
|
27
|
+
/** Record a FAILED attempt; returns attempts remaining (≥ 0). */
|
|
28
|
+
recordFailure(ip: string): number;
|
|
29
|
+
/** Clear an IP's counter on a successful PIN entry. */
|
|
30
|
+
recordSuccess(ip: string): void;
|
|
31
|
+
private current;
|
|
32
|
+
private load;
|
|
33
|
+
private persist;
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=PinAttemptStore.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PinAttemptStore.d.ts","sourceRoot":"","sources":["../../src/core/PinAttemptStore.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAUH,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,OAAO,CAAmC;IAClD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAe;gBAEvB,IAAI,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAA;KAAE;IAUnG,gDAAgD;IAChD,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAK5B,iEAAiE;IACjE,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM;IAWjC,uDAAuD;IACvD,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IAI/B,OAAO,CAAC,OAAO;IAUf,OAAO,CAAC,IAAI;IAYZ,OAAO,CAAC,OAAO;CAUhB"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PinAttemptStore — durable write-through behind the PIN routes' per-IP
|
|
3
|
+
* brute-force lockout (docs/specs/routing-control-room-spend-alerts.md,
|
|
4
|
+
* Surface 2, S2-1 hardening).
|
|
5
|
+
*
|
|
6
|
+
* `checkMandatePin`'s attempt counter was an in-memory Map, so a server restart
|
|
7
|
+
* reset the lockout. This store persists the counters to
|
|
8
|
+
* `<stateDir>/state/pin-attempts.json` (atomic tmp+rename) and is shared by the
|
|
9
|
+
* PIN routes. Semantics unchanged: N attempts per window per IP; the window
|
|
10
|
+
* expiry clears the entry. Express `trust proxy` is off fleet-wide, so req.ip
|
|
11
|
+
* already ignores X-Forwarded-For.
|
|
12
|
+
*/
|
|
13
|
+
import fs from 'node:fs';
|
|
14
|
+
import path from 'node:path';
|
|
15
|
+
export class PinAttemptStore {
|
|
16
|
+
filePath;
|
|
17
|
+
entries = new Map();
|
|
18
|
+
maxAttempts;
|
|
19
|
+
windowMs;
|
|
20
|
+
now;
|
|
21
|
+
constructor(opts) {
|
|
22
|
+
const stateSub = path.join(opts.stateDir, 'state');
|
|
23
|
+
fs.mkdirSync(stateSub, { recursive: true });
|
|
24
|
+
this.filePath = path.join(stateSub, 'pin-attempts.json');
|
|
25
|
+
this.maxAttempts = opts.maxAttempts ?? 5;
|
|
26
|
+
this.windowMs = opts.windowMs ?? 5 * 60 * 1000;
|
|
27
|
+
this.now = opts.now ?? (() => Date.now());
|
|
28
|
+
this.load();
|
|
29
|
+
}
|
|
30
|
+
/** True when the IP is currently locked out. */
|
|
31
|
+
blocked(ip) {
|
|
32
|
+
const e = this.current(ip);
|
|
33
|
+
return e !== undefined && e.count >= this.maxAttempts;
|
|
34
|
+
}
|
|
35
|
+
/** Record a FAILED attempt; returns attempts remaining (≥ 0). */
|
|
36
|
+
recordFailure(ip) {
|
|
37
|
+
let e = this.current(ip);
|
|
38
|
+
if (!e) {
|
|
39
|
+
e = { count: 0, resetAt: this.now() + this.windowMs };
|
|
40
|
+
this.entries.set(ip, e);
|
|
41
|
+
}
|
|
42
|
+
e.count++;
|
|
43
|
+
this.persist();
|
|
44
|
+
return Math.max(0, this.maxAttempts - e.count);
|
|
45
|
+
}
|
|
46
|
+
/** Clear an IP's counter on a successful PIN entry. */
|
|
47
|
+
recordSuccess(ip) {
|
|
48
|
+
if (this.entries.delete(ip))
|
|
49
|
+
this.persist();
|
|
50
|
+
}
|
|
51
|
+
current(ip) {
|
|
52
|
+
const e = this.entries.get(ip);
|
|
53
|
+
if (e && this.now() > e.resetAt) {
|
|
54
|
+
this.entries.delete(ip);
|
|
55
|
+
this.persist();
|
|
56
|
+
return undefined;
|
|
57
|
+
}
|
|
58
|
+
return e;
|
|
59
|
+
}
|
|
60
|
+
load() {
|
|
61
|
+
try {
|
|
62
|
+
const raw = JSON.parse(fs.readFileSync(this.filePath, 'utf-8'));
|
|
63
|
+
for (const [ip, e] of Object.entries(raw)) {
|
|
64
|
+
if (e && Number.isInteger(e.count) && Number.isFinite(e.resetAt))
|
|
65
|
+
this.entries.set(ip, e);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
// @silent-fallback-ok: absent/corrupt attempt file — start empty. The lockout
|
|
70
|
+
// is defence-in-depth; an unreadable file must not brick PIN auth entirely.
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
persist() {
|
|
74
|
+
try {
|
|
75
|
+
const tmp = this.filePath + '.tmp';
|
|
76
|
+
fs.writeFileSync(tmp, JSON.stringify(Object.fromEntries(this.entries)), { mode: 0o600 });
|
|
77
|
+
fs.renameSync(tmp, this.filePath);
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
// @silent-fallback-ok: a failed persist degrades to in-memory-only counters
|
|
81
|
+
// (today's behavior) — never blocks the auth decision itself.
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=PinAttemptStore.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PinAttemptStore.js","sourceRoot":"","sources":["../../src/core/PinAttemptStore.ts"],"names":[],"mappings":"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"}
|
|
@@ -50,6 +50,13 @@ export declare function DOORWAY_REGISTRY_CLAUDEMD_SECTION(port: number): string;
|
|
|
50
50
|
* controls (caps adjust, go-live, gate) are Increment B and NOT surfaced as capabilities.
|
|
51
51
|
*/
|
|
52
52
|
export declare function ROUTING_SPEND_CLAUDEMD_SECTION(port: number): string;
|
|
53
|
+
/**
|
|
54
|
+
* CLAUDE.md awareness block for the Routing Control Room MONEY layer (Increment B —
|
|
55
|
+
* ledger + fail-closed gate + PIN caps/arming). Unique content-sniff marker:
|
|
56
|
+
* `Routing Spend MONEY layer`. Ships DARK for everyone (DARK_GATE_EXCLUSIONS
|
|
57
|
+
* action-bearing; FD-16) — the section says so honestly (Maturity Honesty).
|
|
58
|
+
*/
|
|
59
|
+
export declare function ROUTING_SPEND_MONEY_CLAUDEMD_SECTION(port: number): string;
|
|
53
60
|
export interface MigrationResult {
|
|
54
61
|
/** What was upgraded */
|
|
55
62
|
upgraded: string[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PostUpdateMigrator.d.ts","sourceRoot":"","sources":["../../src/core/PostUpdateMigrator.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"PostUpdateMigrator.d.ts","sourceRoot":"","sources":["../../src/core/PostUpdateMigrator.ts"],"names":[],"mappings":"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"}
|