Skip to content

Add replay continuity evaluation benchmark and V7 replay adapter#71

Merged
ProfRandom92 merged 1 commit into
mainfrom
codex/implement-comptextv7-replay-continuity-evaluation
May 13, 2026
Merged

Add replay continuity evaluation benchmark and V7 replay adapter#71
ProfRandom92 merged 1 commit into
mainfrom
codex/implement-comptextv7-replay-continuity-evaluation

Conversation

@ProfRandom92

Copy link
Copy Markdown
Owner

Motivation

  • Provide a deterministic evaluation that measures semantic/operational replay continuity instead of token reduction.
  • Exercise CompText V7 against adversarial probes (hidden constraints, temporal confusion, architecture mutation, contradictory instructions, dependency-order and semantic ambiguity) to reveal real failure modes.
  • Enable reproducible, visual comparison across naive, baseline, adaptive, and comptext_v7 replay strategies for long chains (10+, 25+, 50+ iterations).

Description

  • Add src/validation/replay_continuity.py implementing SemanticReplayState, V7ReplayAdapter, ComparativeReplayAdapter, adversarial ReplayScenarios, ContinuityMetrics, iterative run_replay_chain/run_comparison, deterministic artifact serialization, and SVG visualizers.
  • Add CLI runner benchmarks/run_replay_continuity.py that calls write_benchmark_artifacts and supports configurable chain lengths; include a small sys.path shim so it runs from the repo.
  • Add tests tests/test_replay_continuity.py that validate V7 retention across 50 iterations, comparative ordering (naive < baseline < adaptive < comptext_v7), chain-length support (10/25/50+), and deterministic artifact generation.
  • Commit generated deterministic artifacts under reports/replay_continuity/, including comparison_summary.json and SVGs for degradation curves, heatmap, semantic drift, longevity, and contradiction accumulation; the produced summary reports comptext_v7 as preserving full continuity in the committed 50-iteration run.

Testing

  • Ran the benchmark runner with python benchmarks/run_replay_continuity.py --iterations 50 --output-dir reports/replay_continuity and it produced deterministic artifacts at reports/replay_continuity/ including comparison_summary.json and SVG visualizations.
  • Executed the new scenario/unit tests with pytest tests/test_replay_continuity.py and they passed (4 passed).
  • Ran the full test suite with python -m pytest -q and all tests passed (23 passed), and the artifact determinism check (writing artifacts twice and comparing) succeeded.

Codex Task

@vercel

vercel Bot commented May 13, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
comptextv7 Ready Ready Preview, Comment May 13, 2026 4:57pm

@netlify

netlify Bot commented May 13, 2026

Copy link
Copy Markdown

Deploy Preview for comptext-v7 canceled.

Name Link
🔨 Latest commit 3ea5f3f
🔍 Latest deploy log https://app.netlify.com/projects/comptext-v7/deploys/6a04ad5b14dcc80008b624dd

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

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.

Code Review

This pull request introduces a new replay continuity evaluation framework for CompText V7, including a benchmark runner, adversarial scenarios, and SVG-based visualizations for semantic drift and continuity metrics. The code changes include a new validation module in src/validation/replay_continuity.py and corresponding tests. The review comments identified several areas for improvement, specifically regarding PEP 8 line length compliance for dictionary definitions and adding robustness guards against potential ZeroDivisionError and ValueError exceptions in the evaluation and visualization logic.

Comment on lines +321 to +329
if self.mode == "naive":
budgets = {"goals": 1, "constraints": max(0, 2 - iteration // 4), "anchors": max(0, 1 - iteration // 6), "truths": max(0, 2 - iteration // 5), "clusters": max(0, 1 - iteration // 7), "deps": max(0, 2 - iteration // 5)}
mutation_period = 5
elif self.mode == "baseline":
budgets = {"goals": max(1, 2 - iteration // 18), "constraints": max(1, 4 - iteration // 9), "anchors": max(1, 3 - iteration // 10), "truths": max(1, 4 - iteration // 8), "clusters": max(1, 2 - iteration // 14), "deps": max(1, 3 - iteration // 11)}
mutation_period = 9
else: # adaptive
budgets = {"goals": max(1, 3 - iteration // 30), "constraints": max(1, 6 - iteration // 15), "anchors": max(1, 4 - iteration // 16), "truths": max(1, 6 - iteration // 14), "clusters": max(1, 3 - iteration // 20), "deps": max(1, 5 - iteration // 18)}
mutation_period = 17

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

These lines are excessively long (over 200 characters), which significantly hinders readability and violates standard Python style guidelines (PEP 8). Breaking the budgets dictionaries into multiple lines would improve maintainability.

        if self.mode == "naive":
            budgets = {
                "goals": 1,
                "constraints": max(0, 2 - iteration // 4),
                "anchors": max(0, 1 - iteration // 6),
                "truths": max(0, 2 - iteration // 5),
                "clusters": max(0, 1 - iteration // 7),
                "deps": max(0, 2 - iteration // 5),
            }
            mutation_period = 5
        elif self.mode == "baseline":
            budgets = {
                "goals": max(1, 2 - iteration // 18),
                "constraints": max(1, 4 - iteration // 9),
                "anchors": max(1, 3 - iteration // 10),
                "truths": max(1, 4 - iteration // 8),
                "clusters": max(1, 2 - iteration // 14),
                "deps": max(1, 3 - iteration // 11),
            }
            mutation_period = 9
        else:  # adaptive
            budgets = {
                "goals": max(1, 3 - iteration // 30),
                "constraints": max(1, 6 - iteration // 15),
                "anchors": max(1, 4 - iteration // 16),
                "truths": max(1, 6 - iteration // 14),
                "clusters": max(1, 3 - iteration // 20),
                "deps": max(1, 5 - iteration // 18),
            }
            mutation_period = 17

Comment on lines +602 to +603
"mean_final_continuity": round(sum(final_scores) / len(final_scores), 6),
"mean_longevity_iterations": round(sum(longevities) / len(longevities), 3),

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

Potential ZeroDivisionError if final_scores or longevities are empty. While the current scenarios are hardcoded, adding a guard ensures the benchmark runner remains robust if scenarios are filtered or modified in the future.

Suggested change
"mean_final_continuity": round(sum(final_scores) / len(final_scores), 6),
"mean_longevity_iterations": round(sum(longevities) / len(longevities), 3),
"mean_final_continuity": round(sum(final_scores) / len(final_scores), 6) if final_scores else 0.0,
"mean_longevity_iterations": round(sum(longevities) / len(longevities), 3) if longevities else 0.0,

Comment on lines +669 to +670
series = _series_by_mode(chains, metric)
max_len = max(len(values) for values in series.values())

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 max() function will raise a ValueError if series is empty (e.g., if no chains were processed). Adding a check for an empty series improves the robustness of the visualization logic.

Suggested change
series = _series_by_mode(chains, metric)
max_len = max(len(values) for values in series.values())
series = _series_by_mode(chains, metric)
if not series:
return ""
max_len = max(len(values) for values in series.values())

Comment on lines +705 to +706
finals = [chain for chain in chains if isinstance(chain, dict) and chain["mode"] == mode]
value = sum(float(chain["iterations"][-1]["metrics"][metric]) for chain in finals) / len(finals) # type: ignore[index]

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

Potential ZeroDivisionError if finals is empty for a given mode. It is safer to check if the list has elements before performing the division.

Suggested change
finals = [chain for chain in chains if isinstance(chain, dict) and chain["mode"] == mode]
value = sum(float(chain["iterations"][-1]["metrics"][metric]) for chain in finals) / len(finals) # type: ignore[index]
finals = [chain for chain in chains if isinstance(chain, dict) and chain["mode"] == mode]
value = sum(float(chain["iterations"][-1]["metrics"][metric]) for chain in finals) / len(finals) if finals else 0.0 # type: ignore[index]

@ProfRandom92 ProfRandom92 merged commit 58a1b38 into main May 13, 2026
10 checks passed
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