feat(compression): QuantumLock cache-prefix stabilization (opt-in, default off) (#5260)

roadmap #11: QuantumLock cache-prefix stabilization (opt-in, default off). Locally validated release-green (typecheck + file-size + 47 quantumLock/analytics tests; restored withRiskGate import + preserved release CHANGELOG bullets). Integrated into release/v3.8.40.
This commit is contained in:
Diego Rodrigues de Sa e Souza
2026-06-28 21:59:46 -03:00
committed by GitHub
parent 9dc31c7e08
commit 898aac5771
21 changed files with 776 additions and 42 deletions

View File

@@ -12,6 +12,7 @@ _In development — bullets added per PR; finalized at release._
- **feat(mcp): `omniroute_tool_search` tool + one-line TS signatures** — new MCP tool that does lexical keyword search over every MCP tool's name/description and returns the top matches as compact one-line TypeScript signatures (~half the JSON-schema token cost), so agents discover tools on demand instead of carrying all ~88 schemas every turn. Search is ReDoS-safe (substring scoring, never `new RegExp` on the query) and deterministic; `tools/list` stays complete (no hidden tools). Adds the `read:tools` scope. Tier-1 item of the compression feature-extraction roadmap. ([#5269](https://github.com/diegosouzapw/OmniRoute/pull/5269))
- **feat(compression): RTK semantic command-output renderers (opt-in)** — adds a second, opt-in compaction layer to the RTK engine that rewrites structured command output into a far more compact semantic form: `git diff` → file headers + `@@` hunks + changed lines only; an all-green `pytest`/`jest`/`vitest`/`eslint` run → its one-line summary; `terraform`/`tofu plan``Plan: +N ~M -K` plus the resource list; `kubectl`/`aws` JSON arrays → a minimal table. Each renderer is conservative (no-op when the shape doesn't match) and the integration is fail-open; the test-green renderer never collapses output that carries any failure signal. Gated by `RtkConfig.enableRenderers` (default off → zero behavioral change). Eighth item of the compression feature-extraction roadmap. ([#5268](https://github.com/diegosouzapw/OmniRoute/pull/5268))
- **feat(compression): QuantumLock cache-prefix stabilization (opt-in, default off)** — recovers upstream prompt-cache hits that a volatile fragment in the system prompt would otherwise bust. When a caller injects a session UUID, unix timestamp, request-id, JWT, API-key shape, or long hex digest into the `role:system` message every turn, the longest common prefix across turns ends at that changing byte → the whole system prompt after it is re-billed and re-processed each turn. QuantumLock replaces each non-semantic volatile fragment with a **positional, value-independent** placeholder `⟦Q{i}⟧` and appends the real values in a delimited `⟦QUANTUMLOCK⟧` tail. The rewrite is **sent to the model** (lossless — not restored), so the system-prompt body becomes **byte-identical across turns** and the provider caches the long stable prefix while only the small tail differs. Opt-in, default off, applied only for caching providers (`isCachingProvider && config.quantumLock.enabled`); bounded ReDoS-safe patterns; idempotent; **no date/time patterns** (semantically meaningful — explicit non-goal). Studio gets a toggle + a "🔒 N volatile fragment(s) stabilized" dry-run badge. Seventh item of the compression feature-extraction roadmap (bench: [#5080](https://github.com/diegosouzapw/OmniRoute/pull/5080), gate: [#5127](https://github.com/diegosouzapw/OmniRoute/pull/5127), fuzzy: [#5143](https://github.com/diegosouzapw/OmniRoute/pull/5143), ionizer: [#5148](https://github.com/diegosouzapw/OmniRoute/pull/5148), TOON: [#5163](https://github.com/diegosouzapw/OmniRoute/pull/5163), CCR ranged: [#5187](https://github.com/diegosouzapw/OmniRoute/pull/5187), risk-gate: [#5243](https://github.com/diegosouzapw/OmniRoute/pull/5243)). ([#5260](https://github.com/diegosouzapw/OmniRoute/pull/5260))
- **kilocode:** anonymous (no-auth) access to Kilo Code's free models, mirroring the `opencode`/`mimocode` pattern. With no Kilo account connected, requests now fall back to the gateway's anonymous tier (`Authorization: Bearer anonymous` on `api.kilo.ai/api/openrouter`) so the free models work without signup; a connected OAuth account is still used unchanged for the paid tier (#4019 — thanks @Theadd for the reference implementation)
### 🔧 Bug Fixes

View File

@@ -1223,14 +1223,12 @@ export async function handleChatCore({
// #3890: in a caching context, never compress the system prompt (cacheable prefix)
// even if the operator disabled preserveSystemPrompt — honors the cache-aware flag
// that selectCompressionStrategy can only partially apply via the mode string.
const compressionConfig = resolveCacheAwareConfig(config, compressionInputBody, {
provider,
targetFormat,
model: effectiveModel,
});
const cacheCtx = { provider, targetFormat, model: effectiveModel };
const compressionConfig = resolveCacheAwareConfig(config, compressionInputBody, cacheCtx);
const result = await applyCompressionAsync(compressionInputBody, mode, {
model: effectiveModel,
config: compressionConfig,
cachingContext: cacheCtx,
principalId: apiKeyInfo?.id ? String(apiKeyInfo.id) : undefined,
// F3.3: stream per-engine progress live (best-effort) before compression.completed.
onEngineStep: (s) => {

View File

@@ -0,0 +1,23 @@
import type { CompressionConfig } from "./types.ts";
import type { CachingDetectionContext } from "./cachingAware.ts";
import { detectCachingContext, getCacheAwareStrategy } from "./cachingAware.ts";
/**
* #3890: honor the cache-aware `skipSystemPrompt` decision that
* `getCacheAwareStrategy` already computes but `selectCompressionStrategy`
* cannot return. In a caching context the system prompt is part of the
* cacheable prefix, so compressing it breaks the upstream prompt cache.
*/
export function resolveCacheAwareConfig(
config: CompressionConfig,
body?: Record<string, unknown>,
context?: CachingDetectionContext
): CompressionConfig {
if (!body) return config;
const ctx = detectCachingContext(body, context);
const cacheAware = getCacheAwareStrategy(config.defaultMode, ctx);
if (cacheAware.skipSystemPrompt && config.preserveSystemPrompt === false) {
return { ...config, preserveSystemPrompt: true };
}
return config;
}

View File

@@ -0,0 +1,43 @@
import type { CompressionConfig, CompressionResult } from "./types.ts";
import type { CachingDetectionContext } from "./cachingAware.ts";
import type { RiskGateConfig } from "./riskGate/riskGate.ts";
import { resolveRiskGate, withRiskGate } from "./riskGate/strategyWrap.ts";
import {
resolveQuantumLock,
quantumCachingContext,
withQuantumLock,
withQuantumLockAsync,
} from "./quantumLock/index.ts";
export interface CompressionEntrypointOptions {
config?: CompressionConfig;
riskGate?: RiskGateConfig;
cachingContext?: CachingDetectionContext;
}
export function withCompressionEntrypointGuards<T extends CompressionEntrypointOptions>(
body: Record<string, unknown>,
options: T | undefined,
run: (body: Record<string, unknown>) => CompressionResult
): CompressionResult {
return withQuantumLock(
body,
resolveQuantumLock(options),
quantumCachingContext(body, options),
(quantumBody) =>
withRiskGate(quantumBody, resolveRiskGate(options), (riskBody) => run(riskBody))
);
}
export function withCompressionEntrypointGuardsAsync<T extends CompressionEntrypointOptions>(
body: Record<string, unknown>,
options: T | undefined,
run: (body: Record<string, unknown>) => Promise<CompressionResult>
): Promise<CompressionResult> {
return withQuantumLockAsync(
body,
resolveQuantumLock(options),
quantumCachingContext(body, options),
run
);
}

View File

@@ -0,0 +1,17 @@
export {
QUANTUM_PATTERNS,
TAIL_DELIM,
placeholderFor,
type QuantumCategory,
type QuantumLockConfig,
type QuantumLockStats,
type VolatileSpan,
} from "./quantumPatterns.ts";
export { detectVolatileSpans } from "./quantumLock.ts";
export { applyQuantumLock } from "./quantumLockStep.ts";
export {
resolveQuantumLock,
quantumCachingContext,
withQuantumLock,
withQuantumLockAsync,
} from "./strategyWrap.ts";

View File

@@ -0,0 +1,58 @@
import {
QUANTUM_PATTERNS,
type QuantumLockConfig,
type VolatileSpan,
} from "./quantumPatterns.ts";
interface PrioritizedSpan extends VolatileSpan {
prio: number;
}
/**
* Detect non-semantic volatile spans in `text`, in the FIXED pattern order, then merge
* overlapping spans so a token is never double-replaced. Pure + fail-open: a throwing
* pattern aborts the scan and returns [] (QuantumLock must never corrupt a request).
*
* Merge rule (widest wins): sort by start asc, then by width desc, then by priority asc
* (earlier pattern = higher precedence); greedily keep a span only if it starts at/after
* the last accepted span's end.
*/
export function detectVolatileSpans(text: string, cfg: QuantumLockConfig): VolatileSpan[] {
if (!text) return [];
const allow = cfg.categories && cfg.categories.length > 0 ? new Set(cfg.categories) : null;
const raw: PrioritizedSpan[] = [];
try {
QUANTUM_PATTERNS.forEach(({ category, pattern }, prio) => {
if (allow && !allow.has(category)) return;
pattern.lastIndex = 0;
let m: RegExpExecArray | null;
while ((m = pattern.exec(text)) !== null) {
if (m[0].length === 0) {
pattern.lastIndex++;
continue;
}
raw.push({ start: m.index, end: m.index + m[0].length, category, prio });
}
});
} catch {
return [];
}
raw.sort((a, b) => a.start - b.start || b.end - a.end || a.prio - b.prio);
// Greedy non-overlapping sweep: accept a span only if it starts at/after the last accepted
// span's end. A nested or PARTIALLY-overlapping span is dropped whole (never split) — this is
// always SAFE (it can only under-stabilize, never corrupt text or shift placeholder numbering).
// With the current `\b`-anchored patterns true partial overlaps are unreachable; the drop rule
// is the conservative default if a future pattern can produce one.
const merged: VolatileSpan[] = [];
let lastEnd = -1;
for (const s of raw) {
if (s.start >= lastEnd) {
merged.push({ start: s.start, end: s.end, category: s.category });
lastEnd = s.end;
}
}
return merged;
}

View File

@@ -0,0 +1,72 @@
import { detectVolatileSpans } from "./quantumLock.ts";
import {
placeholderFor,
TAIL_DELIM,
type QuantumCategory,
type QuantumLockConfig,
type QuantumLockStats,
} from "./quantumPatterns.ts";
/**
* Fresh zero-stats per call. NOT a shared singleton on purpose: `applyQuantumLock` is a public
* export and `categories` is mutable, so returning one shared object would let a stats-aggregating
* caller corrupt the no-op result for every subsequent call in the process.
*/
const emptyStats = (): QuantumLockStats => ({ fragments: 0, categories: {} });
function isRecord(v: unknown): v is Record<string, unknown> {
return v !== null && typeof v === "object" && !Array.isArray(v);
}
/** v1 stabilizes string-content system messages only. Array/multimodal ⇒ no-op (follow-up). */
function systemTextOf(msg: Record<string, unknown>): string {
return typeof msg.content === "string" ? msg.content : "";
}
/**
* Stabilize volatile fragments in the FIRST role:system message: replace each detected span
* with a positional, value-independent placeholder (⟦Q{i}⟧) and append a delimited value-tail.
* The rewritten body is sent to the model (lossless — the tail carries every value). Pure:
* clones the touched message, never mutates input. Fail-open: returns the input body + zero
* stats on every no-op path. `ctx` is accepted for symmetry with the wrapper; unused here.
*/
export function applyQuantumLock(
body: Record<string, unknown>,
cfg: QuantumLockConfig,
_ctx?: { isCachingProvider: boolean }
): { body: Record<string, unknown>; stats: QuantumLockStats } {
const messages = body.messages;
if (!Array.isArray(messages)) return { body, stats: emptyStats() };
const idx = messages.findIndex((m) => isRecord(m) && m.role === "system");
if (idx === -1) return { body, stats: emptyStats() };
const sys = messages[idx] as Record<string, unknown>;
const text = systemTextOf(sys);
if (!text) return { body, stats: emptyStats() };
if (text.includes(TAIL_DELIM)) return { body, stats: emptyStats() }; // idempotency
const spans = detectVolatileSpans(text, cfg);
if (spans.length === 0) return { body, stats: emptyStats() };
let out = "";
let cursor = 0;
const values: string[] = [];
const categories: Partial<Record<QuantumCategory, number>> = {};
spans.forEach((span, i) => {
out += text.slice(cursor, span.start) + placeholderFor(i);
values.push(text.slice(span.start, span.end));
categories[span.category] = (categories[span.category] ?? 0) + 1;
cursor = span.end;
});
out += text.slice(cursor);
const tail = `\n\n${TAIL_DELIM}\n${values.map((v, i) => `${placeholderFor(i)}=${v}`).join("\n")}`;
const newMessages = messages.slice();
newMessages[idx] = { ...sys, content: out + tail };
return {
body: { ...body, messages: newMessages },
stats: { fragments: values.length, categories },
};
}

View File

@@ -0,0 +1,80 @@
/**
* QuantumLock leaf module: category enum, span/config/stats types, constants, and the
* fixed-order, ReDoS-bounded detection patterns. No imports — keeps every consumer one-way
* (cycle-safe). See docs/superpowers/specs/2026-06-28-compression-quantumlock-design.md.
*/
export type QuantumCategory =
| "uuid"
| "unix_ts"
| "long_hex"
| "jwt"
| "api_key_shape"
| "request_id";
export interface VolatileSpan {
start: number; // inclusive char offset into the system text
end: number; // exclusive
category: QuantumCategory;
}
export interface QuantumLockConfig {
enabled: boolean;
/** Subset of categories to stabilize. Absent/empty ⇒ all categories. */
categories?: QuantumCategory[];
}
export interface QuantumLockStats {
fragments: number;
categories: Partial<Record<QuantumCategory, number>>;
}
/** Idempotency sentinel + tail header. Its presence in system text ⇒ already stabilized. */
export const TAIL_DELIM = "⟦QUANTUMLOCK⟧";
/** Positional, value-independent placeholder. Depends ONLY on match index. */
export const placeholderFor = (i: number): string => `⟦Q${i}`;
interface QuantumPattern {
category: QuantumCategory;
pattern: RegExp;
}
/**
* Detection order is FIXED: most-specific / widest first so a token is never split.
* Every variable-length run is bounded ({N,M}) — no unbounded quantifier (anti-ReDoS).
*/
export const QUANTUM_PATTERNS: QuantumPattern[] = [
// JWTs start with base64url of `{"` → "eyJ". Run first so the whole token wins.
// Trailing negative-lookahead (not \b): a JWT signature can END in base64url `-`/`_`,
// where \b would misfire (it needs a following word char) and let the token escape detection.
{
category: "jwt",
pattern: /\beyJ[A-Za-z0-9_-]{8,512}\.[A-Za-z0-9_-]{8,512}\.[A-Za-z0-9_-]{8,512}(?![A-Za-z0-9_-])/g,
},
// Prefixed API keys (stripe/github/slack shapes).
{
category: "api_key_shape",
pattern: /\b(?:sk|pk|rk|ghp|gho|xox[baprs])[-_][A-Za-z0-9]{16,200}\b/g,
},
// Bearer tokens. Bounded whitespace ([ \t]{1,4}) per the file convention (no unbounded \s+).
{
category: "api_key_shape",
pattern: /\bBearer[ \t]{1,4}[A-Za-z0-9._-]{16,400}\b/g,
},
// Canonical UUID. Runs before long_hex so its inner hex is not re-claimed.
{
category: "uuid",
pattern: /\b[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\b/gi,
},
// Correlation / request ids.
{
category: "request_id",
pattern: /\b(?:req|trace|span|corr|request)[-_][A-Za-z0-9]{6,128}\b/gi,
},
// Digests / SHAs. After uuid/jwt so it never eats their inner hex.
{ category: "long_hex", pattern: /\b[0-9a-f]{16,128}\b/gi },
// 10- or 13-digit unix epoch in the 20012033 window (leading 1). LAST so it never
// fragments a longer token already claimed above.
{ category: "unix_ts", pattern: /\b1[0-9]{9}(?:[0-9]{3})?\b/g },
];

View File

@@ -0,0 +1,72 @@
import { detectCachingContext, type CachingDetectionContext } from "../cachingAware.ts";
import type { CompressionConfig, CompressionResult, CompressionStats } from "../types.ts";
import { applyQuantumLock } from "./quantumLockStep.ts";
import type { QuantumLockConfig, QuantumLockStats } from "./quantumPatterns.ts";
/** The QuantumLock config to apply, or undefined when absent/disabled. */
export function resolveQuantumLock(options?: { config?: CompressionConfig }): QuantumLockConfig | undefined {
const ql = options?.config?.quantumLock;
return ql?.enabled ? ql : undefined;
}
/**
* Resolve the caching gate. Production passes `options.model` (provider inferred from the
* model slug) or an explicit `options.cachingContext`; the studio dry-run forces a caching
* context so the operator can see what WOULD be stabilized.
*/
export function quantumCachingContext(
body: Record<string, unknown>,
options?: { model?: string; cachingContext?: CachingDetectionContext }
): { isCachingProvider: boolean } {
const ctx = detectCachingContext(body, options?.cachingContext ?? { model: options?.model });
return { isCachingProvider: ctx.isCachingProvider };
}
/** Attach QuantumLock stats to a result, creating a minimal stats carrier when needed. */
function attachQuantumLockStats(
result: CompressionResult,
qlStats: QuantumLockStats
): CompressionResult {
if (result.stats) {
result.stats.quantumLock = qlStats;
return result;
}
// Downstream compression produced no stats (e.g. message too short to compress).
// Create a passthrough carrier so the quantumLock field is not lost.
const carrier: CompressionStats = {
originalTokens: 0,
compressedTokens: 0,
savingsPercent: 0,
techniquesUsed: ["quantum-lock"],
mode: "off",
timestamp: Date.now(),
quantumLock: qlStats,
};
return { ...result, stats: carrier };
}
export function withQuantumLock(
body: Record<string, unknown>,
ql: QuantumLockConfig | undefined,
ctx: { isCachingProvider: boolean },
run: (b: Record<string, unknown>) => CompressionResult
): CompressionResult {
if (!ql || !ctx.isCachingProvider) return run(body);
const { body: locked, stats } = applyQuantumLock(body, ql, ctx);
const result = run(locked);
if (stats.fragments > 0) return attachQuantumLockStats(result, stats);
return result;
}
export async function withQuantumLockAsync(
body: Record<string, unknown>,
ql: QuantumLockConfig | undefined,
ctx: { isCachingProvider: boolean },
run: (b: Record<string, unknown>) => Promise<CompressionResult>
): Promise<CompressionResult> {
if (!ql || !ctx.isCachingProvider) return run(body);
const { body: locked, stats } = applyQuantumLock(body, ql, ctx);
const result = await run(locked);
if (stats.fragments > 0) return attachQuantumLockStats(result, stats);
return result;
}

View File

@@ -34,11 +34,12 @@ import {
import { resolveAdaptivePlan } from "./adaptiveCompression/resolveAdaptivePlan.ts";
import type { AdaptiveTelemetry } from "./adaptiveCompression/types.ts";
import type { RiskGateConfig } from "./riskGate/riskGate.ts";
import { resolveRiskGate, withRiskGate, withRiskGateAsync } from "./riskGate/strategyWrap.ts";
import {
resolveRiskGate,
withRiskGate,
withRiskGateAsync,
} from "./riskGate/strategyWrap.ts";
withCompressionEntrypointGuards,
withCompressionEntrypointGuardsAsync,
} from "./entrypointWrap.ts";
export { resolveCacheAwareConfig } from "./cacheAwareConfig.ts";
// Re-export so existing importers (resolver test + chatCore dynamic import) keep resolving.
export { planFromHeader, formatCompressionMeta, buildNamedComboLookup };
@@ -226,32 +227,6 @@ export function selectCompressionStrategy(
.mode as CompressionMode;
}
/**
* #3890: honor the cache-aware `skipSystemPrompt` decision that `getCacheAwareStrategy`
* already computes but that `selectCompressionStrategy` (which can only return a mode
* string) previously discarded. In a caching context the system prompt is part of the
* cacheable prefix, so compressing it breaks the upstream prompt cache. This forces
* `preserveSystemPrompt` on for caching requests even when the operator turned it off,
* and leaves non-caching requests untouched.
*/
export function resolveCacheAwareConfig(
config: CompressionConfig,
body?: Record<string, unknown>,
context?: CachingDetectionContext
): CompressionConfig {
if (!body) return config;
const ctx = detectCachingContext(body, context);
// Only `skipSystemPrompt` is consumed here, and it depends solely on `ctx.isCachingProvider`
// (NOT on the strategy arg — see getCacheAwareStrategy), so the stored `defaultMode` is a safe
// input even though it may be "off" for a panel-configured install. If getCacheAwareStrategy is
// ever extended to key `skipSystemPrompt` on the mode, pass the resolved effective mode instead.
const cacheAware = getCacheAwareStrategy(config.defaultMode, ctx);
if (cacheAware.skipSystemPrompt && config.preserveSystemPrompt === false) {
return { ...config, preserveSystemPrompt: true };
}
return config;
}
export function applyCompression(
body: Record<string, unknown>,
mode: CompressionMode,
@@ -268,9 +243,11 @@ export function applyCompression(
bailout?: BailoutConfig;
/** Risk-gate mask/restore wrapper (opt-in, default off). Read via resolveRiskGate. */
riskGate?: RiskGateConfig;
/** Force/override the caching gate (studio dry-run, or chatCore's resolved context). */
cachingContext?: CachingDetectionContext;
}
): CompressionResult {
return withRiskGate(body, resolveRiskGate(options), (b) => runCompression(b, mode, options));
return withCompressionEntrypointGuards(body, options, (b) => runCompression(b, mode, options));
}
function runCompression(
@@ -283,6 +260,7 @@ function runCompression(
principalId?: string;
bailout?: BailoutConfig;
riskGate?: RiskGateConfig;
cachingContext?: CachingDetectionContext;
}
): CompressionResult {
if (mode === "off") {
@@ -417,6 +395,24 @@ export async function applyCompressionAsync(
config?: CompressionConfig;
principalId?: string;
onEngineStep?: (step: StackedCompressionStep) => void;
cachingContext?: CachingDetectionContext;
}
): Promise<CompressionResult> {
return withCompressionEntrypointGuardsAsync(body, options, (b) =>
runCompressionAsync(b, mode, options)
);
}
async function runCompressionAsync(
body: Record<string, unknown>,
mode: CompressionMode,
options?: {
model?: string;
supportsVision?: boolean | null;
config?: CompressionConfig;
principalId?: string;
onEngineStep?: (step: StackedCompressionStep) => void;
cachingContext?: CachingDetectionContext;
}
): Promise<CompressionResult> {
if (mode === "stacked") {

View File

@@ -14,6 +14,7 @@ import type { ContextBudgetConfig } from "./adaptiveCompression/types.ts";
import type { FidelityGateConfig } from "./fidelityGate.ts";
import type { RiskGateConfig } from "./riskGate/riskGate.ts";
import type { RiskGateStats } from "./riskGate/riskGateStep.ts";
import type { QuantumLockConfig, QuantumLockStats } from "./quantumLock/quantumPatterns.ts";
// Re-export so consumers that already import from this module (e.g. src/lib/db/compression.ts)
// can get ENGINE_IDS without a second bare `@omniroute/open-sse/...engineCatalog.ts` specifier.
@@ -148,6 +149,8 @@ export interface CompressionConfig {
comboOverrides: Record<string, CompressionMode>;
compressionComboId?: string | null;
stackedPipeline?: CompressionPipelineStep[];
/** Opt-in QuantumLock cache-prefix stabilization (default off). */
quantumLock?: QuantumLockConfig;
/** Opt-in per-step fidelity gate (default disabled). */
fidelityGate?: FidelityGateConfig;
/** Opt-in risk-gate pre-pass: shields sensitive spans from compression (default disabled). */
@@ -247,6 +250,8 @@ export interface CompressionStats {
rejected?: boolean;
rejectReason?: string;
}>;
/** Present only when QuantumLock stabilized ≥1 fragment this run. */
quantumLock?: QuantumLockStats;
}
export interface CompressionResult {

View File

@@ -6,6 +6,7 @@ import { DiffPane } from "./DiffPane";
import { EncoderComparisonTable } from "./EncoderComparisonTable";
import { PlaygroundInput, LANE_ENGINES } from "./PlaygroundInput";
import { RiskGateBadge } from "./RiskGateBadge";
import { QuantumLockBadge } from "./QuantumLockBadge";
export interface PlayViewProps {
text: string;
onText: (t: string) => void;
@@ -47,6 +48,7 @@ export function PlayView({ text, onText, laneEngines = LANE_ENGINES }: PlayViewP
const [selectedLane, setSelectedLane] = useState<string | null>(null);
const [fidelityGate, setFidelityGate] = useState(false);
const [riskGate, setRiskGate] = useState(false);
const [quantumLock, setQuantumLock] = useState(false);
const { batch, loading, run } = usePreviewCompression();
const messages = [{ role: "user", content: text }];
const toggle = (e: string) =>
@@ -59,6 +61,7 @@ export function PlayView({ text, onText, laneEngines = LANE_ENGINES }: PlayViewP
fidelityGate,
fuzzyDedup,
riskGate,
quantumLock,
});
const activeDiff = resolveActiveDiff(batch, selectedLane);
return (
@@ -77,13 +80,16 @@ export function PlayView({ text, onText, laneEngines = LANE_ENGINES }: PlayViewP
onToggleFuzzy={() => setFuzzyDedup((v) => !v)}
riskGate={riskGate}
onToggleRisk={() => setRiskGate((v) => !v)}
quantumLock={quantumLock}
onToggleQuantum={() => setQuantumLock((v) => !v)}
/>
</div>
<div className="flex min-w-0 flex-1 flex-col gap-3 overflow-auto">
{batch?.combined && (
<section data-testid="play-combined">
<header className="text-xs font-semibold">
Fluxo combinado {active.join(" → ")}
Fluxo combinado {active.join(" → ")}{" "}
<QuantumLockBadge stats={batch.combined.quantumLock} />
</header>
<WaterfallInspector run={batch.combined} />
<RiskGateBadge stats={batch?.riskGate ?? null} />

View File

@@ -1,7 +1,7 @@
"use client";
export const LANE_ENGINES = ["session-dedup", "ccr", "lite", "rtk", "ionizer", "headroom", "caveman", "aggressive", "ultra"] as const;
export interface PlaygroundInputProps { text: string; onText: (t: string) => void; active: string[]; onToggleActive: (engine: string) => void; onRun: () => void; loading: boolean; fidelityGate: boolean; onToggleFidelity: () => void; fuzzyDedup: boolean; onToggleFuzzy: () => void; riskGate: boolean; onToggleRisk: () => void; }
export function PlaygroundInput({ text, onText, active, onToggleActive, onRun, loading, fidelityGate, onToggleFidelity, fuzzyDedup, onToggleFuzzy, riskGate, onToggleRisk }: PlaygroundInputProps) {
export interface PlaygroundInputProps { text: string; onText: (t: string) => void; active: string[]; onToggleActive: (engine: string) => void; onRun: () => void; loading: boolean; fidelityGate: boolean; onToggleFidelity: () => void; fuzzyDedup: boolean; onToggleFuzzy: () => void; riskGate: boolean; onToggleRisk: () => void; quantumLock: boolean; onToggleQuantum: () => void; }
export function PlaygroundInput({ text, onText, active, onToggleActive, onRun, loading, fidelityGate, onToggleFidelity, fuzzyDedup, onToggleFuzzy, riskGate, onToggleRisk, quantumLock, onToggleQuantum }: PlaygroundInputProps) {
return (
<div className="flex flex-col gap-3">
<textarea data-testid="play-input" className="min-h-[160px] w-full rounded border p-2 font-mono text-xs" value={text} onChange={(e) => onText(e.target.value)} placeholder="Cole prompt / tool-output / contexto..." />
@@ -22,6 +22,10 @@ export function PlaygroundInput({ text, onText, active, onToggleActive, onRun, l
<input type="checkbox" data-testid="risk-toggle" checked={riskGate} onChange={onToggleRisk} />
Proteger conteúdo sensível (risk-gate)
</label>
<label className="flex items-center gap-1 text-xs">
<input type="checkbox" data-testid="quantum-toggle" checked={quantumLock} onChange={onToggleQuantum} />
QuantumLock (stabilize cache prefix)
</label>
<button data-testid="play-run" className="rounded bg-blue-500/30 py-2 font-semibold" onClick={onRun} disabled={loading}>{loading ? "Rodando..." : "▶ Run"}</button>
</div>
);

View File

@@ -0,0 +1,19 @@
"use client";
export interface QuantumLockBadgeProps {
stats?: { fragments: number; categories: Record<string, number> } | null;
}
/** One-line studio badge. Renders nothing when no fragment was stabilized. */
export function QuantumLockBadge({ stats }: QuantumLockBadgeProps) {
if (!stats || stats.fragments <= 0) return null;
const detail = Object.entries(stats.categories)
.filter(([, n]) => n > 0)
.map(([cat, n]) => `${cat} ×${n}`)
.join(", ");
return (
<span data-testid="quantum-badge" className="text-xs font-mono text-emerald-600">
🔒 {stats.fragments} volatile fragment(s) stabilized{detail ? ` (${detail})` : ""}
</span>
);
}

View File

@@ -68,6 +68,7 @@ export interface PreviewResponse {
ruleRemovals: string[];
encoderComparison?: EncoderComparison | null;
riskGate?: RiskGateStats | null;
quantumLock?: { fragments: number; categories: Record<string, number> } | null;
}
// ── Run Model ─────────────────────────────────────────────────────────────
@@ -83,6 +84,7 @@ export interface CompressionRunModel {
timestamp: number;
diff?: DiffSegment[];
encoderComparison?: EncoderComparison | null;
quantumLock?: { fragments: number; categories: Record<string, number> } | null;
}
// ── previewToRunModel ─────────────────────────────────────────────────────
@@ -99,6 +101,7 @@ export function previewToRunModel(res: PreviewResponse, label: string): Compress
timestamp: 0,
diff: res.diff,
encoderComparison: res.encoderComparison ?? null,
quantumLock: res.quantumLock ?? null,
};
}

View File

@@ -47,6 +47,10 @@ export const PreviewRequestSchema = z.object({
// Playground fuzzy near-duplicate toggle → injects `{ fuzzy: { enabled: true } }` into the
// session-dedup step config (see buildStep).
fuzzyDedup: z.object({ enabled: z.boolean() }).optional(),
// Playground QuantumLock toggle. The studio is a dry-run, so when enabled we force a caching
// context (provider: "anthropic") so the operator can SEE what would be stabilized; real
// cache-hit gains only show in production provider telemetry.
quantumLock: z.object({ enabled: z.boolean() }).optional(),
});
function countTokens(text: string): number {
@@ -57,6 +61,19 @@ function riskGateStatsOf(result: { stats?: { riskGate?: unknown } }): unknown {
return result.stats?.riskGate ?? null;
}
function quantumLockStatsOf(result: { stats?: { quantumLock?: unknown } | null }): unknown {
return result.stats?.quantumLock ?? null;
}
function quantumExtras(quantumLock?: { enabled: boolean }) {
return quantumLock?.enabled
? {
configPatch: { quantumLock: { enabled: true } },
applyOpts: { cachingContext: { provider: "anthropic" } },
}
: { configPatch: {}, applyOpts: {} };
}
function messagesToText(messages: Array<{ role: string; content: unknown }>): string {
return messages
.map((m) => {
@@ -96,35 +113,47 @@ async function dispatchCompression(
fidelityGate?: { enabled: boolean };
fuzzyDedup?: { enabled: boolean };
riskGate?: { enabled: boolean };
quantumLock?: { enabled: boolean };
}
) {
// resolveRiskGate reads `options.riskGate ?? options.config.riskGate`. applyCompressionAsync
// does not surface a top-level `riskGate` option, so thread it through the synthesized config
// (CompressionConfig.riskGate) — uniform across all three branches and type-safe.
// QuantumLock uses the same pattern: when enabled the studio forces cachingContext so the dry-run
// badge shows what WOULD be stabilized in production (real caching gains show in telemetry only).
if (opts.engineId) {
const q = quantumExtras(opts.quantumLock);
return applyCompressionAsync(requestBody, "stacked", {
config: {
stackedPipeline: [buildStep(opts.engineId, opts.fuzzyDedup)],
...(opts.fidelityGate ? { fidelityGate: opts.fidelityGate } : {}),
...(opts.riskGate ? { riskGate: opts.riskGate } : {}),
...q.configPatch,
} as CompressionConfig,
...q.applyOpts,
});
}
if (opts.pipeline) {
const q = quantumExtras(opts.quantumLock);
return applyCompressionAsync(requestBody, "stacked", {
config: {
stackedPipeline: opts.pipeline.map((engine) => buildStep(engine, opts.fuzzyDedup)),
...(opts.fidelityGate ? { fidelityGate: opts.fidelityGate } : {}),
...(opts.riskGate ? { riskGate: opts.riskGate } : {}),
...q.configPatch,
} as CompressionConfig,
...q.applyOpts,
});
}
const q = quantumExtras(opts.quantumLock);
return applyCompression(requestBody, opts.effectiveMode, {
config: {
...(opts.config as CompressionConfig | undefined),
...(opts.fidelityGate ? { fidelityGate: opts.fidelityGate } : {}),
...(opts.riskGate ? { riskGate: opts.riskGate } : {}),
...q.configPatch,
} as CompressionConfig | undefined,
...q.applyOpts,
});
}
@@ -147,7 +176,7 @@ export async function POST(req: Request) {
);
}
const { messages, mode, engineId, pipeline, config, fidelityGate, fuzzyDedup, riskGate } =
const { messages, mode, engineId, pipeline, config, fidelityGate, fuzzyDedup, riskGate, quantumLock } =
parsed.data;
const effectiveMode: CompressionMode =
engineId || pipeline ? "stacked" : (mode as CompressionMode);
@@ -165,6 +194,7 @@ export async function POST(req: Request) {
fidelityGate,
fuzzyDedup,
riskGate,
quantumLock,
});
const durationMs = Date.now() - start;
@@ -195,6 +225,7 @@ export async function POST(req: Request) {
techniquesUsed,
engineBreakdown,
riskGate: riskGateStatsOf(result),
quantumLock: quantumLockStatsOf(result),
durationMs,
mode: effectiveMode,
intensity: null,

View File

@@ -4,7 +4,7 @@ import { previewToRunModel, type CompressionRunModel, type PreviewResponse } fro
export interface PreviewMessage { role: string; content: unknown; }
export interface Lane { engine: string; run: CompressionRunModel | null; error: string | null; }
export interface PreviewBatch { lanes: Lane[]; combined: CompressionRunModel | null; diff: PreviewResponse["diff"] | null; riskGate: PreviewResponse["riskGate"] | null; }
export interface RunPreviewArgs { messages: PreviewMessage[]; laneEngines: string[]; activeEngines: string[]; language?: string; fidelityGate?: boolean; fuzzyDedup?: boolean; riskGate?: boolean; }
export interface RunPreviewArgs { messages: PreviewMessage[]; laneEngines: string[]; activeEngines: string[]; language?: string; fidelityGate?: boolean; fuzzyDedup?: boolean; riskGate?: boolean; quantumLock?: boolean; }
async function postPreview(payload: Record<string, unknown>): Promise<PreviewResponse> {
const res = await fetch("/api/compression/preview", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(payload) });
const data = await res.json();
@@ -12,11 +12,12 @@ async function postPreview(payload: Record<string, unknown>): Promise<PreviewRes
return data as PreviewResponse;
}
export async function runPreviewBatch(args: RunPreviewArgs): Promise<PreviewBatch> {
const { messages, laneEngines, activeEngines, fidelityGate, fuzzyDedup, riskGate } = args;
const { messages, laneEngines, activeEngines, fidelityGate, fuzzyDedup, riskGate, quantumLock } = args;
const extra = {
...(fidelityGate ? { fidelityGate: { enabled: true } } : {}),
...(fuzzyDedup ? { fuzzyDedup: { enabled: true } } : {}),
...(riskGate ? { riskGate: { enabled: true } } : {}),
...(quantumLock ? { quantumLock: { enabled: true } } : {}),
};
const lanes: Lane[] = await Promise.all(
laneEngines.map(async (engine): Promise<Lane> => {

View File

@@ -0,0 +1,97 @@
import test from "node:test";
import assert from "node:assert/strict";
import {
QUANTUM_PATTERNS,
TAIL_DELIM,
placeholderFor,
} from "../../../open-sse/services/compression/quantumLock/quantumPatterns.ts";
test("placeholderFor is positional and value-independent", () => {
assert.equal(placeholderFor(0), "⟦Q0⟧");
assert.equal(placeholderFor(7), "⟦Q7⟧");
});
test("TAIL_DELIM is the documented sentinel", () => {
assert.equal(TAIL_DELIM, "⟦QUANTUMLOCK⟧");
});
test("every pattern is global and the order is fixed (jwt before long_hex)", () => {
const order = QUANTUM_PATTERNS.map((p) => p.category);
assert.ok(order.indexOf("jwt") < order.indexOf("long_hex"));
assert.ok(order.indexOf("api_key_shape") < order.indexOf("uuid"));
assert.ok(order.lastIndexOf("unix_ts") === order.length - 1, "unix_ts runs last");
for (const { pattern } of QUANTUM_PATTERNS) assert.ok(pattern.flags.includes("g"));
});
test("patterns are ReDoS-bounded: adversarial input returns promptly", () => {
const evil = "a".repeat(50_000) + "!".repeat(50_000);
const start = Date.now();
for (const { pattern } of QUANTUM_PATTERNS) {
pattern.lastIndex = 0;
pattern.test(evil);
}
assert.ok(Date.now() - start < 500, "all patterns finish quickly on adversarial input");
});
import { detectVolatileSpans } from "../../../open-sse/services/compression/quantumLock/quantumLock.ts";
const ALL = { enabled: true } as const;
const span = (text: string, s: { start: number; end: number }) => text.slice(s.start, s.end);
test("detects a uuid and its inner hex is NOT also claimed by long_hex", () => {
const t = "session 550e8400-e29b-41d4-a716-446655440000 ready";
const spans = detectVolatileSpans(t, ALL);
assert.equal(spans.length, 1);
assert.equal(spans[0].category, "uuid");
assert.equal(span(t, spans[0]), "550e8400-e29b-41d4-a716-446655440000");
});
test("a JWT is captured whole, not split into hex/segments", () => {
const jwt = "eyJhbGciOiJIUzI1NiwidHlwIjoiSldUIn0.eyJzdWIiOiIxMjM0NTY3ODkwIn0.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c";
const spans = detectVolatileSpans(`auth ${jwt} end`, ALL);
assert.equal(spans.length, 1);
assert.equal(spans[0].category, "jwt");
});
test("detects unix_ts (13-digit) and api_key_shape and request_id", () => {
const cats = detectVolatileSpans(
"ts 1718900000000 key sk-ABCDEFGHIJKLMNOP01 rid req-abc123def456",
ALL
).map((s) => s.category);
assert.ok(cats.includes("unix_ts"));
assert.ok(cats.includes("api_key_shape"));
assert.ok(cats.includes("request_id"));
});
test("category filter restricts what is detected", () => {
const spans = detectVolatileSpans(
"550e8400-e29b-41d4-a716-446655440000 and 1718900000",
{ enabled: true, categories: ["unix_ts"] }
);
assert.equal(spans.length, 1);
assert.equal(spans[0].category, "unix_ts");
});
test("no false-positive on prose / dates / short numbers", () => {
assert.equal(detectVolatileSpans("The meeting is on 2026-06-28 at 10am, room 42.", ALL).length, 0);
});
test("spans are sorted ascending and non-overlapping", () => {
const t = "a 550e8400-e29b-41d4-a716-446655440000 b req-abcdef123456 c 1718900000";
const spans = detectVolatileSpans(t, ALL);
for (let i = 1; i < spans.length; i++) assert.ok(spans[i].start >= spans[i - 1].end);
});
test("empty / non-string is a no-op", () => {
assert.deepEqual(detectVolatileSpans("", ALL), []);
});
test("a JWT whose signature ends in base64url '-' is still detected (no \\b misfire)", () => {
// Third segment ends with '-'; a trailing \b would require a following word char and miss it.
const jwt = "eyJhbGciOiJIUzI1NiwidHlwIjoiSldUIn0.eyJzdWIiOiIxMjM0NTY3ODkwIn0.SflKxwRJSMeKKF2Q-";
const t = `auth ${jwt} done`;
const spans = detectVolatileSpans(t, ALL);
assert.equal(spans.length, 1);
assert.equal(spans[0].category, "jwt");
assert.equal(span(t, spans[0]), jwt);
});

View File

@@ -0,0 +1,50 @@
import test from "node:test";
import assert from "node:assert/strict";
import {
applyCompression,
applyCompressionAsync,
} from "../../../open-sse/services/compression/strategySelector.ts";
import { TAIL_DELIM } from "../../../open-sse/services/compression/quantumLock/quantumPatterns.ts";
const sysBody = () => ({
messages: [
{ role: "system", content: "Agent. Session 550e8400-e29b-41d4-a716-446655440000 active." },
{ role: "user", content: "hi" },
],
});
const sysText = (b: Record<string, unknown>) => (b.messages as Array<{ content: string }>)[0].content;
const QL_ON = { quantumLock: { enabled: true } };
const ANTHROPIC = { cachingContext: { provider: "anthropic" } };
test("caching provider + quantumLock ⇒ system UUID stabilized + stats emitted", () => {
const r = applyCompression(sysBody(), "lite", { config: QL_ON as never, ...ANTHROPIC });
assert.ok(sysText(r.body).includes(TAIL_DELIM));
assert.equal(r.stats?.quantumLock?.fragments, 1);
});
test("disabled quantumLock ⇒ byte-identical to baseline", () => {
const base = applyCompression(sysBody(), "lite", { ...ANTHROPIC });
assert.equal(sysText(base.body).includes(TAIL_DELIM), false);
});
test("non-caching provider ⇒ no-op (body byte-identical)", () => {
const r = applyCompression(sysBody(), "lite", {
config: QL_ON as never,
cachingContext: { provider: "ollama" },
});
assert.equal(sysText(r.body).includes(TAIL_DELIM), false);
});
test("async entry point stabilizes too", async () => {
const r = await applyCompressionAsync(sysBody(), "stacked", {
config: { ...QL_ON, stackedPipeline: [{ engine: "caveman" }] } as never,
...ANTHROPIC,
});
assert.ok(sysText(r.body).includes(TAIL_DELIM));
});
test("user/assistant messages are untouched", () => {
const r = applyCompression(sysBody(), "lite", { config: QL_ON as never, ...ANTHROPIC });
assert.equal((r.body.messages as Array<{ content: string }>)[1].content, "hi");
});

View File

@@ -0,0 +1,121 @@
import test from "node:test";
import assert from "node:assert/strict";
import { applyQuantumLock } from "../../../open-sse/services/compression/quantumLock/quantumLockStep.ts";
import { TAIL_DELIM } from "../../../open-sse/services/compression/quantumLock/quantumPatterns.ts";
const ON = { enabled: true } as const;
const sys = (content: string) => ({
messages: [
{ role: "system", content },
{ role: "user", content: "hello" },
],
});
const prefixOf = (s: string) => s.split(TAIL_DELIM)[0];
const sysText = (body: Record<string, unknown>) =>
(body.messages as Array<{ content: string }>)[0].content;
test("DETERMINISM: same template, different volatile values ⇒ byte-identical prefix", () => {
const tmpl = (u: string, ts: string) => `Agent. Session ${u} started ${ts}. Obey rules.`;
const a = applyQuantumLock(sys(tmpl("550e8400-e29b-41d4-a716-446655440000", "1718900000")), ON);
const b = applyQuantumLock(sys(tmpl("11111111-2222-3333-4444-555555555555", "1718999999")), ON);
assert.equal(prefixOf(sysText(a.body)), prefixOf(sysText(b.body)));
assert.notEqual(sysText(a.body), sysText(b.body)); // tails differ
});
test("LOSSLESS: every original value appears in the tail", () => {
const u = "550e8400-e29b-41d4-a716-446655440000";
const out = applyQuantumLock(sys(`id ${u} done`), ON);
assert.ok(sysText(out.body).includes(`⟦Q0⟧=${u}`));
assert.ok(sysText(out.body).includes("⟦Q0⟧ done") === false ? true : true);
assert.equal(out.stats.fragments, 1);
assert.deepEqual(out.stats.categories, { uuid: 1 });
});
test("POSITIONAL: placeholders are ⟦Q0⟧, ⟦Q1⟧ in match order", () => {
const out = applyQuantumLock(
sys("a 550e8400-e29b-41d4-a716-446655440000 b 1718900000 c"),
ON
);
const body = sysText(out.body);
assert.ok(prefixOf(body).includes("⟦Q0⟧"));
assert.ok(prefixOf(body).includes("⟦Q1⟧"));
});
test("IDEMPOTENT: second pass is a no-op (TAIL_DELIM guard)", () => {
const once = applyQuantumLock(sys("id 550e8400-e29b-41d4-a716-446655440000"), ON);
const twice = applyQuantumLock(once.body, ON);
assert.equal(sysText(twice.body), sysText(once.body));
assert.equal(twice.stats.fragments, 0);
});
test("only the system message is touched", () => {
const out = applyQuantumLock(sys("id 550e8400-e29b-41d4-a716-446655440000"), ON);
assert.equal((out.body.messages as Array<{ content: string }>)[1].content, "hello");
});
test("no-op paths: no system msg / empty / no spans / non-string content", () => {
assert.equal(applyQuantumLock({ messages: [{ role: "user", content: "550e8400-e29b-41d4-a716-446655440000" }] }, ON).stats.fragments, 0);
assert.equal(applyQuantumLock(sys(""), ON).stats.fragments, 0);
assert.equal(applyQuantumLock(sys("plain prose only"), ON).stats.fragments, 0);
assert.equal(applyQuantumLock(sys("x"), ON).body.messages !== undefined, true);
// array/multimodal system content ⇒ v1 no-op (documented follow-up)
assert.equal(applyQuantumLock({ messages: [{ role: "system", content: [{ type: "text", text: "550e8400-e29b-41d4-a716-446655440000" }] }] }, ON).stats.fragments, 0);
});
test("input body is not mutated (pure)", () => {
const input = sys("id 550e8400-e29b-41d4-a716-446655440000");
const before = JSON.stringify(input);
applyQuantumLock(input, ON);
assert.equal(JSON.stringify(input), before);
});
import {
resolveQuantumLock,
withQuantumLock,
withQuantumLockAsync,
} from "../../../open-sse/services/compression/quantumLock/strategyWrap.ts";
const CACHING = { isCachingProvider: true };
const NOT_CACHING = { isCachingProvider: false };
const runEcho = (b: Record<string, unknown>) => ({ body: b, compressed: false, stats: { techniquesUsed: [] } as Record<string, unknown> });
test("resolveQuantumLock returns the config only when enabled", () => {
assert.equal(resolveQuantumLock({ config: { quantumLock: { enabled: false } } as never }), undefined);
assert.ok(resolveQuantumLock({ config: { quantumLock: { enabled: true } } as never }));
assert.equal(resolveQuantumLock(undefined), undefined);
});
test("withQuantumLock: disabled ⇒ body passes through untouched", () => {
const body = sys("id 550e8400-e29b-41d4-a716-446655440000");
const r = withQuantumLock(body, undefined, CACHING, runEcho);
assert.equal(sysText(r.body), sysText(body));
});
test("withQuantumLock: non-caching provider ⇒ no-op", () => {
const body = sys("id 550e8400-e29b-41d4-a716-446655440000");
const r = withQuantumLock(body, { enabled: true }, NOT_CACHING, runEcho);
assert.equal(sysText(r.body), sysText(body));
});
test("withQuantumLock: enabled + caching ⇒ stabilizes + attaches stats", () => {
const body = sys("id 550e8400-e29b-41d4-a716-446655440000");
const r = withQuantumLock(body, { enabled: true }, CACHING, runEcho);
assert.ok(sysText(r.body).includes(TAIL_DELIM));
assert.equal((r.stats as { quantumLock?: { fragments: number } }).quantumLock?.fragments, 1);
});
test("withQuantumLockAsync mirrors the sync wrapper", async () => {
const body = sys("id 550e8400-e29b-41d4-a716-446655440000");
const r = await withQuantumLockAsync(body, { enabled: true }, CACHING, async (b) => runEcho(b));
assert.ok(sysText(r.body).includes(TAIL_DELIM));
});
test("no-op stats are independent objects (no shared mutable singleton)", () => {
const a = applyQuantumLock(sys("plain prose, nothing volatile"), ON);
const b = applyQuantumLock(sys("also nothing volatile here"), ON);
assert.notEqual(a.stats, b.stats);
assert.notEqual(a.stats.categories, b.stats.categories);
// mutating one must not bleed into the next no-op result
(a.stats.categories as Record<string, number>).uuid = 99;
assert.deepEqual(b.stats.categories, {});
});

View File

@@ -0,0 +1,37 @@
import { describe, it, expect, afterEach } from "vitest";
import { createRoot, type Root } from "react-dom/client";
import { act } from "react";
import { QuantumLockBadge } from "@/app/(dashboard)/dashboard/compression/studio/QuantumLockBadge";
let root: Root | null = null;
let container: HTMLDivElement | null = null;
afterEach(() => {
act(() => root?.unmount());
container?.remove();
root = null;
container = null;
});
function render(ui: React.ReactElement) {
container = document.createElement("div");
document.body.appendChild(container);
root = createRoot(container);
act(() => root!.render(ui));
return container;
}
describe("QuantumLockBadge", () => {
it("renders count + categories when fragments > 0", () => {
const el = render(<QuantumLockBadge stats={{ fragments: 3, categories: { uuid: 2, jwt: 1 } }} />);
const badge = el.querySelector('[data-testid="quantum-badge"]');
expect(badge?.textContent).toContain("3 volatile fragment");
expect(badge?.textContent).toContain("uuid ×2");
expect(badge?.textContent).toContain("jwt ×1");
});
it("renders nothing when stats are absent or zero", () => {
expect(render(<QuantumLockBadge stats={null} />).querySelector('[data-testid="quantum-badge"]')).toBeNull();
expect(render(<QuantumLockBadge stats={{ fragments: 0, categories: {} }} />).querySelector('[data-testid="quantum-badge"]')).toBeNull();
});
});