Skip to content

Commit dd6c60b

Browse files
committed
feat(runtime): cap the registries, flights, and retained diagnostics
Every operational registry now answers admission before work begins: turns at the fetch boundary, WebSockets before the upgrade, storage workers and mutation homes before spawning, credential-refresh and pool-quota flights before their requests, catalog gathers before providers are contacted. Diagnostic rings and fixed slots account their bytes and truncate on a UTF-8 boundary, discovery and usage reads are byte-bounded with truncation made visible through the management API down to the GUI, and the Cursor MCP manager stages its catalog transactionally under typed limits. The shared gate lives in src/lib/admission.ts; the 035 plan doc carries the four audit rounds that moved each cap onto its real owner.
1 parent 90579d4 commit dd6c60b

76 files changed

Lines changed: 2815 additions & 401 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

devlog/_plan/260801_zero_leak_state_stores/035_registry_admission_caps.md

Lines changed: 380 additions & 122 deletions
Large diffs are not rendered by default.

gui/src/components/apikeys-workspace/ApiKeysWorkspace.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ export interface ApiKeysWorkspaceProps {
2626
/** Dataset-level. Absent means nothing is attributable yet — a different
2727
* statement from a key whose counters read zero. */
2828
attributionSince?: string;
29+
historyTruncated?: boolean;
2930
authMatrix: ApiAuthMatrixRow[];
3031
keysLoading: boolean;
3132
keysLoadFailed: boolean;
@@ -62,6 +63,7 @@ export interface ApiKeysWorkspaceProps {
6263
export default function ApiKeysWorkspace({
6364
keys,
6465
attributionSince,
66+
historyTruncated,
6567
authMatrix,
6668
keysLoading,
6769
keysLoadFailed,
@@ -371,7 +373,7 @@ export default function ApiKeysWorkspace({
371373
<dd>{selected.usage.requests7d.toLocaleString(localeTag)}</dd>
372374
</div>
373375
<div className="awi-kv-row">
374-
<dt>{t("api.attribution.totalRequests")}</dt>
376+
<dt>{historyTruncated ? t("api.attribution.totalRequestsAvailable") : t("api.attribution.totalRequests")}</dt>
375377
<dd>{selected.usage.totalRequests.toLocaleString(localeTag)}</dd>
376378
</div>
377379
<div className="awi-kv-row">
@@ -381,7 +383,7 @@ export default function ApiKeysWorkspace({
381383
: t("api.attribution.neverUsed")}</dd>
382384
</div>
383385
<div className="awi-kv-row">
384-
<dt>{t("api.attribution.since")}</dt>
386+
<dt>{historyTruncated ? t("api.attribution.sinceAvailable") : t("api.attribution.since")}</dt>
385387
<dd>{formatCreatedDate(attributionSince, localeTag)}</dd>
386388
</div>
387389
</dl>

gui/src/i18n/de.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -609,6 +609,8 @@ export const de: Record<TKey, string> = {
609609
"usage.empty": "Noch keine Nutzung erfasst. Sende eine Anfrage über den Proxy, um Aktivität hier zu sehen.",
610610
"usage.loadError": "Nutzungsdaten konnten nicht geladen werden.",
611611
"usage.range.all": "Alle",
612+
"usage.range.available": "Verfügbarer Verlauf",
613+
"usage.historyTruncated": "Die Summen beziehen sich nur auf den verfügbaren Verlauf, da ältere Nutzungsdaten nicht geladen wurden.",
612614
"usage.range.30d": "30d",
613615
"usage.range.7d": "7d",
614616
"usage.card.requests": "Anfragen",
@@ -904,6 +906,8 @@ export const de: Record<TKey, string> = {
904906
"api.attribution.title": "Zugeordnete Nutzung",
905907
"api.attribution.requests7d": "Anfragen, letzte 7 Tage",
906908
"api.attribution.totalRequests": "Zugeordnete Anfragen gesamt",
909+
"api.attribution.totalRequestsAvailable": "Anfragen im verfügbaren Verlauf",
910+
"api.attribution.sinceAvailable": "Verfügbare Zuordnung seit",
907911
"api.attribution.lastUsed": "Zuletzt verwendet",
908912
"api.attribution.since": "Zuordnung verfügbar seit",
909913
"api.attribution.neverUsed": "Seit Beginn der Zuordnung nicht verwendet",

gui/src/i18n/en.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -638,6 +638,8 @@ export const en = {
638638
"usage.empty": "No usage recorded yet. Send a request through the proxy to see activity here.",
639639
"usage.loadError": "Could not load usage data.",
640640
"usage.range.all": "All",
641+
"usage.range.available": "Available history",
642+
"usage.historyTruncated": "Totals cover available history only because older usage was not loaded.",
641643
"usage.range.30d": "30d",
642644
"usage.range.7d": "7d",
643645
"usage.card.requests": "Requests",
@@ -1352,6 +1354,8 @@ export const en = {
13521354
"api.attribution.title": "Attributed usage",
13531355
"api.attribution.requests7d": "Requests, last 7 days",
13541356
"api.attribution.totalRequests": "Total attributed requests",
1357+
"api.attribution.totalRequestsAvailable": "Requests in available history",
1358+
"api.attribution.sinceAvailable": "Available attribution since",
13551359
"api.attribution.lastUsed": "Last used",
13561360
"api.attribution.since": "Attribution available since",
13571361
"api.attribution.neverUsed": "Not used since attribution began",

gui/src/i18n/ja.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -598,6 +598,8 @@ export const ja: Record<TKey, string> = {
598598
"usage.empty": "まだ使用量が記録されていません。プロキシ経由でリクエストを送信するとここにアクティビティが表示されます。",
599599
"usage.loadError": "使用量データを読み込めませんでした。",
600600
"usage.range.all": "すべて",
601+
"usage.range.available": "利用可能な履歴",
602+
"usage.historyTruncated": "古い利用履歴が読み込まれていないため、合計は利用可能な履歴のみを対象とします。",
601603
"usage.range.30d": "30日",
602604
"usage.range.7d": "7日",
603605
"usage.card.requests": "リクエスト",
@@ -1300,6 +1302,8 @@ export const ja: Record<TKey, string> = {
13001302
"api.attribution.title": "キー別の使用状況",
13011303
"api.attribution.requests7d": "直近 7 日のリクエスト",
13021304
"api.attribution.totalRequests": "集計済みリクエスト総数",
1305+
"api.attribution.totalRequestsAvailable": "利用可能な履歴のリクエスト",
1306+
"api.attribution.sinceAvailable": "利用可能な集計開始日",
13031307
"api.attribution.lastUsed": "最終使用",
13041308
"api.attribution.since": "集計開始",
13051309
"api.attribution.neverUsed": "集計開始以降は未使用",

gui/src/i18n/ko.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -631,6 +631,8 @@ export const ko: Record<TKey, string> = {
631631
"usage.empty": "아직 기록된 사용량이 없습니다. 프록시로 요청을 보내면 여기에 표시됩니다.",
632632
"usage.loadError": "사용량 데이터를 불러오지 못했습니다.",
633633
"usage.range.all": "전체",
634+
"usage.range.available": "사용 가능한 기록",
635+
"usage.historyTruncated": "이전 사용 기록을 불러오지 않아 합계는 사용 가능한 기록만 포함합니다.",
634636
"usage.range.30d": "30일",
635637
"usage.range.7d": "7일",
636638
"usage.card.requests": "요청",
@@ -931,6 +933,8 @@ export const ko: Record<TKey, string> = {
931933
"api.attribution.title": "키별 사용량",
932934
"api.attribution.requests7d": "최근 7일 요청",
933935
"api.attribution.totalRequests": "집계된 전체 요청",
936+
"api.attribution.totalRequestsAvailable": "사용 가능한 기록의 요청",
937+
"api.attribution.sinceAvailable": "사용 가능한 집계 시작일",
934938
"api.attribution.lastUsed": "마지막 사용",
935939
"api.attribution.since": "집계 시작",
936940
"api.attribution.neverUsed": "집계 이후 사용 없음",

gui/src/i18n/ru.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -630,6 +630,8 @@ export const ru: Record<TKey, string> = {
630630
"usage.empty": "Данных об использовании пока нет. Отправьте запрос через прокси, чтобы увидеть здесь активность.",
631631
"usage.loadError": "Не удалось загрузить данные об использовании.",
632632
"usage.range.all": "Все",
633+
"usage.range.available": "Доступная история",
634+
"usage.historyTruncated": "Итоги охватывают только доступную историю, поскольку старые данные не загружены.",
633635
"usage.range.30d": "30 дн.",
634636
"usage.range.7d": "7 дн.",
635637
"usage.card.requests": "Запросы",
@@ -1342,6 +1344,8 @@ export const ru: Record<TKey, string> = {
13421344
"api.attribution.title": "Использование по ключам",
13431345
"api.attribution.requests7d": "Запросы за 7 дней",
13441346
"api.attribution.totalRequests": "Всего учтённых запросов",
1347+
"api.attribution.totalRequestsAvailable": "Запросы в доступной истории",
1348+
"api.attribution.sinceAvailable": "Доступная атрибуция с",
13451349
"api.attribution.lastUsed": "Последнее использование",
13461350
"api.attribution.since": "Учёт ведётся с",
13471351
"api.attribution.neverUsed": "Не использовался с начала учёта",

gui/src/i18n/zh.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -624,6 +624,8 @@ export const zh: Record<TKey, string> = {
624624
"usage.empty": "尚无用量记录。通过代理发送请求后将在此显示。",
625625
"usage.loadError": "无法加载用量数据。",
626626
"usage.range.all": "全部",
627+
"usage.range.available": "可用历史",
628+
"usage.historyTruncated": "由于未加载较早的使用记录,合计仅涵盖可用历史。",
627629
"usage.range.30d": "30 天",
628630
"usage.range.7d": "7 天",
629631
"usage.card.requests": "请求数",
@@ -924,6 +926,8 @@ export const zh: Record<TKey, string> = {
924926
"api.attribution.title": "按密钥统计的用量",
925927
"api.attribution.requests7d": "最近 7 天请求数",
926928
"api.attribution.totalRequests": "已归属请求总数",
929+
"api.attribution.totalRequestsAvailable": "可用历史中的请求",
930+
"api.attribution.sinceAvailable": "可用归属记录起始时间",
927931
"api.attribution.lastUsed": "最近使用",
928932
"api.attribution.since": "统计起始",
929933
"api.attribution.neverUsed": "统计开始后未使用",

gui/src/pages/ApiKeys.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ interface KeysResponse {
3232
// could not read.
3333
keys?: Array<Omit<ApiKeyEntry, "usage"> & { usage?: ApiKeyEntry["usage"] }>;
3434
attributionSince?: string;
35+
historyTruncated?: boolean;
3536
authMatrix?: unknown;
3637
endpoint?: string;
3738
baseUrl?: string;
@@ -53,6 +54,7 @@ type CachedKeysShape = {
5354
/** Dataset-level: absent means nothing is attributable yet, which is a
5455
* different statement from a key whose counters are zero. */
5556
attributionSince?: string;
57+
historyTruncated?: boolean;
5658
authMatrix: ApiAuthMatrixRow[];
5759
};
5860

@@ -129,6 +131,7 @@ export default function ApiKeys({ apiBase }: { apiBase: string }) {
129131
},
130132
claudeCodeEnabled: data.claudeCodeEnabled !== false,
131133
...(data.attributionSince ? { attributionSince: data.attributionSince } : {}),
134+
...(data.historyTruncated === true ? { historyTruncated: true } : {}),
132135
authMatrix: data.authMatrix,
133136
};
134137
// Prefixes only — never the secret key material.
@@ -180,6 +183,7 @@ export default function ApiKeys({ apiBase }: { apiBase: string }) {
180183
const endpoints = keysData?.endpoints ?? seedEndpointsFromApiBase(apiBase);
181184
const claudeCodeEnabled = keysData?.claudeCodeEnabled ?? true;
182185
const attributionSince = keysData?.attributionSince;
186+
const historyTruncated = keysData?.historyTruncated === true;
183187
// `?? []` only ever fires while there is no key data at all — both the network
184188
// and cache paths reject a payload without a valid matrix, so an empty table
185189
// can never be presented as the server's answer.
@@ -412,6 +416,7 @@ export default function ApiKeys({ apiBase }: { apiBase: string }) {
412416
<ApiKeysWorkspace
413417
keys={keys}
414418
attributionSince={attributionSince}
419+
historyTruncated={historyTruncated}
415420
authMatrix={authMatrix}
416421
keysLoading={false}
417422
keysLoadFailed={keysState.showError}

gui/src/pages/Usage.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,10 @@ interface UsageResponse {
8383
days: UsageDay[];
8484
models: UsageModel[];
8585
providers: UsageProvider[];
86+
historyTruncated: boolean;
87+
truncatedPrefixBytes: number;
88+
entriesTruncated: boolean;
89+
entriesDropped: number;
8690
error?: string;
8791
}
8892

@@ -241,7 +245,7 @@ function UsageFilters({
241245
</div>
242246
<div className="usage-segmented" role="group" aria-label={t("usage.title")}>
243247
{(["all", "30d", "7d"] as Range[]).map(choice => {
244-
const label = t(`usage.range.${choice}`);
248+
const label = choice === "all" ? t("usage.range.available") : t(`usage.range.${choice}`);
245249
return (
246250
<button
247251
key={choice}
@@ -810,6 +814,7 @@ export default function Usage({ apiBase }: { apiBase: string }) {
810814
) : (
811815
<>
812816
{state.showError && <Notice tone="err">{t("usage.loadError")}</Notice>}
817+
{data?.historyTruncated && <Notice tone="ok">{t("usage.historyTruncated")}</Notice>}
813818
{state.refreshing && <DataSurfaceStatus live={!state.showError}>{t("usage.loading")}</DataSurfaceStatus>}
814819
<UsageWorkspaceBody
815820
data={data}

0 commit comments

Comments
 (0)