fix: isolate anonymous rollout rate limits

This commit is contained in:
jb
2026-09-19 10:01:23 -04:00
parent 01b8b4642b
commit 6af610d9ce
6 changed files with 38 additions and 22 deletions
+25 -2
View File
@@ -51,11 +51,34 @@ try {
});
await waitForServer(base, releaseId);
const headers = { origin: base, 'content-type': 'application/json' };
const chat = await fetch(`${base}/api/chat`, { method: 'POST', headers, body: JSON.stringify({ message: '/value', requestId: crypto.randomUUID() }) });
const chatRequest = () => fetch(`${base}/api/chat`, { method: 'POST', headers, body: JSON.stringify({ message: '/value', requestId: crypto.randomUUID() }) });
const chat = await chatRequest();
await assertStatus(chat, 503, 'assistant dispatch');
if (!(await chat.text()).includes('assistant_dispatch')) throw new Error('assistant gate reason missing');
const sync = await fetch(`${base}/api/sync`, { method: 'POST', headers: { origin: base } });
// Chat retains its existing 30-request window for anonymous IPs.
for (let attempt = 2; attempt <= 30; attempt += 1) {
const response = await chatRequest();
await assertStatus(response, 503, `anonymous chat denial ${attempt}`);
await response.text();
}
const chatLimited = await chatRequest();
await assertStatus(chatLimited, 429, 'anonymous chat rate limit');
await chatLimited.text();
const syncRequest = () => fetch(`${base}/api/sync`, { method: 'POST', headers: { origin: base } });
const sync = await syncRequest();
await assertStatus(sync, 503, 'asset sync');
await sync.text();
// The pre-session anonymous sync bucket allows exactly six denials; the
// seventh request is rate-limited. This is intentionally isolated from the
// authenticated trap subprocess below.
for (let attempt = 2; attempt <= 6; attempt += 1) {
const response = await syncRequest();
await assertStatus(response, 503, `anonymous sync denial ${attempt}`);
await response.text();
}
const syncLimited = await syncRequest();
await assertStatus(syncLimited, 429, 'anonymous sync rate limit');
await syncLimited.text();
const token = await fetch(`${base}/api/session/token`);
await assertStatus(token, 503, 'session token');
const characters = await fetch(`${base}/characters`);