feat(compression): opt-in per-step fidelity gate (+ playground toggle) - #5127
Conversation
…nally API-omitted
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
There was a problem hiding this comment.
Code Review
This pull request introduces an opt-in per-step fidelity gate mechanism to prevent compression engines from corrupting critical data (such as protected tokens, numeric literals, JSON keys, and diff hunks). It integrates this gate into the stacked compression selector, updates the preview API and playground UI to support toggling the feature, and adds comprehensive unit and integration tests. Feedback was provided to add defensive checks in bodyToText to handle potentially malformed message elements and prevent runtime crashes.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| function bodyToText(body: Record<string, unknown>): string { | ||
| const messages = body.messages; | ||
| if (!Array.isArray(messages)) return ""; | ||
| return messages.map((m) => extractTextContent((m as { content?: unknown }).content as never)).join("\n"); | ||
| } |
There was a problem hiding this comment.
To prevent potential runtime crashes, add a defensive check to ensure each message m is a non-null object before attempting to access its content property. If messages contains malformed elements (e.g., null, undefined, or primitive values), accessing .content directly will throw a TypeError.
function bodyToText(body: Record<string, unknown>): string {
const messages = body.messages;
if (!Array.isArray(messages)) return "";
return messages
.map((m) => {
if (!m || typeof m !== "object") return "";
return extractTextContent((m as { content?: unknown }).content as never);
})
.join("\n");
}…trategySelector (file-size gate) bodyToText and gateAdvance moved to fidelityGateStep.ts; StackAccumulator exported. strategySelector: 889->854 (-35). Residual +6 vs pre-Milestone-B frozen 848 is the irreducible StackOptions.fidelityGate field + two stacked-loop dispatch reads + import. Baseline updated to 854 with justification. No cycle introduced (import type only). 940 compression tests pass; typecheck clean.
Babysit summary — #5127Status: ready for human review & merge (not auto-merged). I fixed the one red that was this PR's; the rest are pre-existing release-branch drift, proven below. Fixed (this PR's own regression)
Remaining CI red = PRE-EXISTING DRIFT on
|
What
An opt-in, per-step deterministic fidelity gate for the stacked compression pipeline. After each lossy engine,
checkFidelityruns 4 invariants; if the engine's output fails, its output is rejected (the step's input is kept) and theengineBreakdownentry is markedrejected+rejectReason. Default off → byte-identical to today. Second feature of the compression feature-extraction roadmap (validated on the playground bench, PR #5080).Spec/plan:
docs/superpowers/{specs,plans}/2026-06-26-compression-fidelity-gate*(gitignored tooling).The gate
open-sse/services/compression/fidelityGate.ts— purecheckFidelity(inputText, outputText, cfg), 4 invariants (cheap→expensive, short-circuit):preservation.ts(url / const_case / env_var / version / dotted_identifier / function_call / file_path / inline_code; markdown structure excluded to avoid false rejections on legitimate reformatting).@@ -a,b +c,d @@header survives.14 passed → 4 passed, ports, values).packages → pkgskey-rename class).strategySelector.ts):gateAdvanceAND-ed into the 4 advance sites (sync/async × bailout/else). Off →return trueon the first line (zero-cost, byte-identical). Independent of TV1. A no-stats step that fails the gate does not mark the prior engine's breakdown entry (if (result.stats)guard, regression-tested).CompressionConfig.fidelityGate?(opt-in) flows to the gate viaoptions.config.fidelityGate.Playground toggle
A "Verificar fidelidade" checkbox in the studio Play tab passes
fidelityGate:{enabled:true}to/api/compression/preview; rejected lanes show⚠ rejeitado: <invariant>. Verified functionally end-to-end (a preview with a corrupting engine + the flag returnsrejected:true, rejectReason:"número \"8080\" ausente no output"— not an inert flag).Tests
tests/unit/compression/):fidelityGate(8),fidelityGateTypes(1),fidelityGateStacked(3, incl. ON-rejects / OFF-byte-identical / no-stats-hardening),previewRouteFidelity(2).tests/unit/ui/fidelityGateToggle.test.tsx, 1).vitest.config.tsuntouched.CI note — the
check:complexityred is pre-existing DRIFT, not this PRcheck:complexityreports1972 > baseline 1963. Verified the base commitd6f402e0aalready reports 1972 (ran the gate on the base) — i.e. the frozen baseline (1963) is stale vs the currentrelease/v3.8.38state, and this branch adds zero new complexity violations (checkFidelity/gateAdvanceare under the threshold; the flagged functions —applyCompression/applyUltraAsync/applyStackedCompression(Async)— are pre-existing). This is the usual release-branch ratchet drift (rebaselined at release), independent of this PR.Known follow-ups (non-blocking)
{enabled}; the advanced thresholds (minTokenSurvivalPercent/minJsonKeyPercent/checkNumericIntegrity/checkDiffHunks) use conservative defaults until the studio gets a config panel (documented intentional in the route).compressionEventToModel(the WS live-feed path) doesn't propagaterejected/rejectReason— out of scope; for when the live dashboard gains gate support../(e.g.src/lib/db/core.ts) aren't captured bypreservation.tsso aren't in the protected-tokens set — consistent with what the engines protect; extending the path pattern is a system-wide change.Ready for review & merge.