Skip to content

fix(core): remove dead ACT-R decay path, disambiguate ADAPTIVE_DECAY naming (#346) - #388

Merged
cdeust merged 1 commit into
mainfrom
agent/issue-346-decay-cycle-deadcode
Aug 8, 2026
Merged

fix(core): remove dead ACT-R decay path, disambiguate ADAPTIVE_DECAY naming (#346)#388
cdeust merged 1 commit into
mainfrom
agent/issue-346-decay-cycle-deadcode

Conversation

@cdeust

@cdeust cdeust commented Aug 8, 2026

Copy link
Copy Markdown
Owner

Summary

decay_cycle.py's ACT-R base-level-activation block (compute_decay_updates,
compute_actr_base_level, actr_activation_to_heat, _compute_actr_decay)
had zero production callers, and its name (adaptive_decay=True) collides
with the live, published ADAPTIVE_DECAY mechanism that lives elsewhere.

Investigation before deleting

The maintainer flagged mid-task that dead code is more often mis-wired
than abandoned, and asked for git-history evidence before deleting. Traced
the full history of the block:

  1. Wired at the original commit (b80a5998).
  2. Replaced by an ACT-R model in the "zetetic rewrite" commit
    (10359edc, "faithful paper implementations") — still wired.
  3. Deliberately unwired by the A3 migration (b9997157), per an
    explicit design decision:
    docs/program/phase-3-a3-migration-design.md §6
    "Decay cycle post-A3 — DELETE" instructs: "keep the pure-math helpers
    referenced by tests, but unwire from the consolidate handler"
    — because
    memory heat decay moved to the SQL-side lazy effective_heat()
    (pg_schema.py).
  4. The design doc's planned test migration (§6 table:
    test_effective_heat_stage_coefficients etc.) was in fact completed,
    just under different file names:
    tests_py/infrastructure/test_pg_alpha_integral.py,
    test_pg_effective_stage_parity.py, test_pg_decay_clock_anchor.py
    cover the SQL-side equivalent of what test_decay_cycle.py asserted for
    the Python path.

This is a traced, documented supersession decision, not a missed
wiring — deletion is the correct outcome per coding-standards.md §9
("if it's built, it must be called").

Changes

  • mcp_server/core/decay_cycle.py: deleted the ACT-R block, _compute_single_decay,
    and the now-dead-only helpers (_hours_since_access, _hours_since_creation,
    _ACT_R_DECAY_D, _ACT_R_NOISE_S, _MIN_LIFETIME_HOURS,
    _HIGH_IMPORTANCE_THRESHOLD). Kept compute_entity_decay (the only
    production-called function). New module docstring explicitly disambiguates
    the deleted ACT-R model from the live ADAPTIVE_DECAY mechanism
    (thermodynamics.py / pg_recall.py / memory_config.py, behind the
    LoCoMo v3 ablation ΔMRR −0.0163/ΔR@10 −0.020 figure) — closing the
    name-collision.
  • tests_py/core/test_decay_cycle.py: removed the dead-path test classes,
    kept TestComputeEntityDecay.
  • tests_py/benchmarks/benchmark_harness.py (boy-scout): removed
    benchmark_decay_with_emotional_resistance (a standalone __main__
    script, never pytest-collected, calling the now-deleted function) and its
    report section, renumbering the remaining sections to avoid introducing a
    fresh numbering gap.

Acceptance criteria (issue #346)

  • grep -rn "compute_decay_updates\|compute_actr_base_level" mcp_server/ tests_py/ returns nothing.
  • ADAPTIVE_DECAY now resolves to exactly one mechanism (thermodynamics/pg_recall/memory_config), documented at the point a reader is most likely to conflate it (decay_cycle.py's module docstring).
  • No benchmark regression possible — the deleted code had zero production callers, so no live retrieval path changes. Not re-running the full LoCoMo/BEAM suite (machine under heavy shared load; the argument is structural, not measured: an uncalled function cannot change a benchmark result).

Test plan

  • pytest tests_py/core/test_decay_cycle.py tests_py/handlers/consolidation/ — 100 passed
  • pytest tests_py/benchmarks/ tests_py/infrastructure/test_pg_alpha_integral.py tests_py/infrastructure/test_pg_effective_stage_parity.py tests_py/infrastructure/test_pg_decay_clock_anchor.py tests_py/invariants/test_I2_canonical_writer.py — 71 passed
  • Manual smoke of the standalone benchmark_harness.run_all_benchmarks() — runs clean, section numbering verified contiguous
  • ruff check . / ruff format --check . — clean on the full tree
  • Mutation testing (scripts/mutation_check.sh) — not yet run, machine load-gated by the maintainer; exact command below, ready on request:
    scripts/mutation_check.sh "tests_py/core/test_decay_cycle.py tests_py/handlers/consolidation/test_decay.py" mcp_server/core/decay_cycle.py
    

Closes #346

🤖 Generated with Claude Code

…naming (#346)

compute_decay_updates/compute_actr_base_level/actr_activation_to_heat/
_compute_actr_decay in decay_cycle.py had zero production callers — the
consolidation path imports only compute_entity_decay
(handlers/consolidation/decay.py:19).

Investigation before deleting (maintainer directive: dead code is more
often mis-wired than abandoned): git history traces the block through
three states — wired at the original commit, replaced by an ACT-R
model in the "zetetic rewrite" (10359ed), then DELIBERATELY unwired by
the A3 migration (b999715) per an explicit design decision:
docs/program/phase-3-a3-migration-design.md §6 "Decay cycle post-A3 —
DELETE" instructs keeping the pure-math helpers for tests but removing
the consolidate-handler call, because memory heat decay moved to the
SQL-side lazy effective_heat(). The design doc's planned test
migration was in fact completed under different file names
(tests_py/infrastructure/test_pg_alpha_integral.py,
test_pg_effective_stage_parity.py, test_pg_decay_clock_anchor.py cover
the SQL-side equivalent of what test_decay_cycle.py asserted). This is
a traced, documented supersession — not a missed wiring — so deletion
is the correct outcome per coding-standards.md §9.

Deleted the ACT-R block, its now-dead-only helpers
(_compute_single_decay, _hours_since_access, _hours_since_creation,
_ACT_R_DECAY_D, _ACT_R_NOISE_S, _MIN_LIFETIME_HOURS,
_HIGH_IMPORTANCE_THRESHOLD), and the corresponding test classes in
tests_py/core/test_decay_cycle.py. Kept compute_entity_decay (the only
production-called function) and what it needs.

Boy-scout: benchmark_harness.py's compute_decay_updates call
(benchmark_decay_with_emotional_resistance, a standalone __main__
script never collected by pytest) exercised the now-superseded
Ebbinghaus branch — removed it and its report section, renumbering
the remaining sections to avoid introducing a fresh numbering gap.

Rewrote decay_cycle.py's module docstring to disambiguate the deleted
ACT-R model from the live ADAPTIVE_DECAY mechanism (the LoCoMo v3
ablation table's ΔMRR -0.0163/ΔR@10 -0.020) which lives in
thermodynamics.py/pg_recall.py/memory_config.py and never lived in
this file — closing the name-collision a reader could otherwise make.

No benchmark regression possible: the deleted code had no production
caller, so no live retrieval path changes. grep -rn
"compute_decay_updates\|compute_actr_base_level" mcp_server/ tests_py/
now returns nothing.

Targeted tests: tests_py/core/test_decay_cycle.py,
tests_py/handlers/consolidation/, tests_py/benchmarks/,
tests_py/infrastructure/test_pg_alpha_integral.py,
test_pg_effective_stage_parity.py, test_pg_decay_clock_anchor.py,
tests_py/invariants/test_I2_canonical_writer.py — 171 passed.
ruff check + ruff format --check clean on the full tree.

Closes #346

Co-Authored-By: Claude <noreply@anthropic.com>
@cdeust
cdeust merged commit 997b40e into main Aug 8, 2026
21 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

decay_cycle.py: ACT-R base-level path has no production caller, and its name collides with the live ADAPTIVE_DECAY mechanism

1 participant