Skip to content

Add deterministic compression signal engine#87

Merged
ProfRandom92 merged 1 commit into
mainfrom
codex/add-deterministic-compression-signal-engine
May 15, 2026
Merged

Add deterministic compression signal engine#87
ProfRandom92 merged 1 commit into
mainfrom
codex/add-deterministic-compression-signal-engine

Conversation

@ProfRandom92
Copy link
Copy Markdown
Owner

Motivation

  • Provide a lightweight, deterministic cognitive signal layer that treats compression instability as a perception signal for replanning without adding runtime agent complexity.
  • Surface compact, deterministic reasons and a bounded predictionError score so downstream systems can gate deliberation or rollback.
  • Keep the implementation small, pure TypeScript, testable, and consistent with existing foundation patterns.

Description

  • Add a new deterministic Compression Signal Engine implementation in dashboard/app/src/core/foundation/compressionSignals.ts with typed shapes (CognitiveMode, CompressionSignalInput, CompressionSignalWindow, CompressionSignalResult, weights, thresholds, hysteresis, and debounce).
  • Implement signal computations (calculateCompressionRatioDrop, calculateSparseFrameSpike, calculateUnseenSignatureSignal, optional token/replay helpers), MVP calculatePredictionError, and mode classification + sequence evaluation with hysteresis and debounce rules.
  • Add compact sample windows and evaluated results to dashboard/app/src/core/foundation/sampleData.ts and export the utilities via dashboard/app/src/core/foundation/index.ts.
  • Add documentation docs/compression_signal_engine.md describing purpose, Compression is perception claim, input shape, formula, thresholds, hysteresis/debounce rules, cognitive modes, examples, limitations, and next integration points.
  • Add focused tests in tests/test_compression_signals_ts.py that exercise calculations, classification, debounce/hysteresis, rollback immediate trigger, deterministic reason generation, and sample-data validity.

Testing

  • Ran the focused pytest file: pytest tests/test_compression_signals_ts.py -q and it passed (4 passed).
  • Type-check and builds succeeded: npm run typecheck and npm run build for the dashboard and showcase completed without errors.
  • Full test suite succeeded: npm test / pytest -q returned all tests green (existing suite plus new tests; overall 56 passed shown during the run).
  • Repository check succeeded: npm run check (layout, typecheck, validate, build, test) completed with no failures.

Codex Task

@vercel
Copy link
Copy Markdown

vercel Bot commented May 15, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
comptextv7 Ready Ready Preview, Comment May 15, 2026 7:06pm

@netlify
Copy link
Copy Markdown

netlify Bot commented May 15, 2026

Deploy Preview for comptext-v7 canceled.

Name Link
🔨 Latest commit 453a7f2
🔍 Latest deploy log https://app.netlify.com/projects/comptext-v7/deploys/6a076e94f0e37c0008dc63e2

@ProfRandom92 ProfRandom92 merged commit 33bdccc into main May 15, 2026
7 of 10 checks passed
Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces the CompressionSignalEngine, a deterministic telemetry layer designed to monitor compression stability and classify cognitive modes such as 'habit' or 'deliberation'. The implementation includes core logic for signal calculation, hysteresis-based transitions, and a comprehensive test suite. Review feedback highlighted several critical improvements: refining the clamp01 function to correctly handle infinite spikes, resolving logic inconsistencies between stateless and stateful classification, optimizing redundant calculations in window building, and addressing an O(N^2) performance bottleneck in sequence evaluation by limiting history lookback.

Comment on lines +118 to +120
if (!Number.isFinite(value)) {
return 0;
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The clamp01 function returns 0 for all non-finite numbers, including Infinity. In a signal engine, an infinite spike (e.g., in sparseFrameSpike) should logically result in a maximum error score of 1.0 rather than 0. Mapping Infinity to 0 could allow severe anomalies to bypass the trigger thresholds. Consider handling NaN specifically while allowing Infinity to be clamped to 1.

Suggested change
if (!Number.isFinite(value)) {
return 0;
}
if (Number.isNaN(value)) {
return 0;
}
return Math.max(0, Math.min(1, value));

Comment on lines +179 to +194
export function classifyCognitiveMode(predictionError: number, thresholds: CompressionSignalThresholds = defaultCompressionSignalThresholds): CognitiveMode {
const score = clamp01(predictionError);
if (score >= thresholds.rollbackRequiredMin) {
return 'rollback_required';
}
if (score < thresholds.habitMax) {
return 'habit';
}
if (score <= thresholds.monitorMax) {
return 'monitor';
}
if (score >= thresholds.deliberationMin) {
return 'deliberation';
}
return 'monitor';
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The classifyCognitiveMode function implements a stateless classification that is inconsistent with the stateful logic used in the CompressionSignalEngine. It defines its own boundaries (like monitorMax vs deliberationMin) which creates a 'dead zone' or different behavior compared to the engine's hysteresis-based transitions. This duplication of logic is confusing and difficult to maintain.

Comment on lines +196 to +208
function buildSignalWindow(input: CompressionSignalInput, weights: CompressionSignalWeights): CompressionSignalWindow {
const tokenCostSpike = calculateTokenCostSpike(input.tokenEstimate, input.baselineTokenEstimate);
const replayConsistencyDrop = calculateReplayConsistencyDrop(input.replayConsistency, input.baselineReplayConsistency);
return Object.freeze({
input: Object.freeze({ ...input, metadata: input.metadata === undefined ? undefined : Object.freeze({ ...input.metadata }) }),
compressionRatioDrop: calculateCompressionRatioDrop(input.compressionRatio, input.baselineCompressionRatio),
sparseFrameSpike: calculateSparseFrameSpike(input.sparseFrameRate, input.baselineSparseFrameRate),
unseenSignatureSignal: calculateUnseenSignatureSignal(input.unseenSignatureRate),
tokenCostSpike: input.tokenEstimate === undefined || input.baselineTokenEstimate === undefined ? undefined : tokenCostSpike,
replayConsistencyDrop: input.replayConsistency === undefined || input.baselineReplayConsistency === undefined ? undefined : replayConsistencyDrop,
predictionError: calculatePredictionError(input, weights),
});
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The buildSignalWindow function performs redundant calculations. It calls individual signal calculation functions (like calculateTokenCostSpike) and then calls calculatePredictionError, which repeats those same calculations internally. This can be optimized by calculating the signals once and using them for both the window object and the prediction error score.

function buildSignalWindow(input: CompressionSignalInput, weights: CompressionSignalWeights): CompressionSignalWindow {
  const compressionRatioDrop = calculateCompressionRatioDrop(input.compressionRatio, input.baselineCompressionRatio);
  const sparseFrameSpike = calculateSparseFrameSpike(input.sparseFrameRate, input.baselineSparseFrameRate);
  const unseenSignatureSignal = calculateUnseenSignatureSignal(input.unseenSignatureRate);
  const tokenCostSpike = calculateTokenCostSpike(input.tokenEstimate, input.baselineTokenEstimate);
  const replayConsistencyDrop = calculateReplayConsistencyDrop(input.replayConsistency, input.baselineReplayConsistency);

  const predictionError = roundSignal(
    weights.compressionRatioDrop * compressionRatioDrop
      + weights.sparseFrameSpike * sparseFrameSpike
      + weights.unseenSignatureRate * unseenSignatureSignal
      + (weights.tokenCostSpike ?? 0) * tokenCostSpike
      + (weights.replayConsistencyDrop ?? 0) * replayConsistencyDrop,
  );

  return Object.freeze({
    input: Object.freeze({ ...input, metadata: input.metadata === undefined ? undefined : Object.freeze({ ...input.metadata }) }),
    compressionRatioDrop,
    sparseFrameSpike,
    unseenSignatureSignal,
    tokenCostSpike: input.tokenEstimate === undefined || input.baselineTokenEstimate === undefined ? undefined : tokenCostSpike,
    replayConsistencyDrop: input.replayConsistency === undefined || input.baselineReplayConsistency === undefined ? undefined : replayConsistencyDrop,
    predictionError,
  });
}

reasons.push('sparse_frame_rate increased');
}
if (window.unseenSignatureSignal > 0) {
reasons.push(mode === 'deliberation' ? 'unseen_signature_rate remained elevated across debounce window' : 'unseen_signature_rate elevated');
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The reason string 'unseen_signature_rate remained elevated across debounce window' is potentially misleading. It is added whenever unseenSignatureSignal > 0 and the mode is 'deliberation', but being in deliberation mode doesn't guarantee that the unseen signature rate was the specific signal that triggered the transition or satisfied the debounce logic. It might be better to use a more neutral description unless specific attribution logic is implemented.

const windows: CompressionSignalWindow[] = [];
let priorMode = initialMode;
return inputs.map((input) => {
const result = this.evaluateSignalWindow(input, windows, priorMode);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This implementation has O(N^2) time complexity because windows grows with each input and the entire array is passed to evaluateSignalWindow, which performs a spread operation [...priorWindows, window]. Since shouldEnterDeliberation only requires the last debounce.ofLast windows, you should only pass the necessary tail of the history to avoid performance degradation with large input sequences.

Suggested change
const result = this.evaluateSignalWindow(input, windows, priorMode);
const result = this.evaluateSignalWindow(input, windows.slice(-this.debounce.ofLast), priorMode);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant