Skip to content

fix(config): the scheduled-consolidation default includes "mature" - #211

Merged
acidkill merged 1 commit into
acidkill:mainfrom
RobertSigmundsson:fix/scheduled-consolidation-default-missing-mature-strategy
Sep 7, 2026
Merged

acidkill merged 1 commit into
acidkill:mainfrom
RobertSigmundsson:fix/scheduled-consolidation-default-missing-mature-strategy

Conversation

@RobertSigmundsson

Copy link
Copy Markdown
Contributor

Summary

  • MaintenanceConfig's default scheduled-consolidation strategies now include mature, in the field default and in the from_dict fallback.
  • docs/reference/config.md follows, since it is generated from those defaults.
  • Adds a test that pins mature through both paths.

Why

The default tuple was ("prune", "merge", "enrich"). mature is the strategy that owns the EPISODIC to SEMANTIC transition — ConsolidationStrategy.MATURE dispatches to _mature, which is the only place that transition happens — so the scheduled pass on the defaults never promoted anything. The MCP server's own consolidation defaults do include mature, so a deployment driven through MCP still matures; the gap is specific to whatever relies on the scheduled pass.

That matters most for smem serve. Its _consolidation_loop is a plain background task with no operation-triggered auto_consolidate behind it, so if the scheduled pass does not mature, nothing does. The brain accumulates episodic memories indefinitely and nothing errors, which is why this is easy to run into and hard to notice.

Both the field default and the from_dict fallback change, because the HTTP daemon rebuilds MaintenanceConfig from a dict on every reload and would otherwise pick the old tuple straight back up.

A behaviour change worth flagging

On a deployment that has been running on the defaults, the next scheduled pass will start maturing memories it has been leaving alone — a backlog's worth on the first run, in one go. That is the point of the change rather than a side effect, but it is a visible one-off rather than a quiet improvement.

It does not reach everyone. from_dict only falls back to the default when the key is absent, so an installation whose config.toml already records scheduled_consolidation_strategies keeps whatever it has, including the old three. Those operators need to add "mature" themselves; this PR cannot do it for them without editing their configuration, which would be the wrong sort of helpful.

On ordering

Order is not significant. The engine groups strategies into STRATEGY_TIERS, a tuple of frozensets, and runs them tier by tier rather than in the order the configuration lists them. mature sits between merge and enrich for readability, nothing more — worth saying, because the tuple reads like a pipeline and is not one.

Test plan

  • pytest tests/unit/test_scheduled_consolidation_handler.py — 17 passed.
  • With unified_config.py reverted to main and the tests kept, 3 fail: test_defaults, test_from_dict_defaults (both already pinned the tuple and are updated here) and the new test_defaults_include_mature, which asserts through the field default and the from_dict fallback separately.
  • pytest tests/ -m "not stress" -n 4 — 7284 passed, 48 skipped, 1 xfailed, which is main's 7283 plus the one test added here. Two tests in tests/unit/test_dashboard_brains_scope.py fail on this branch and on main alike: they want a live database and collide with one another under -n. Both pass when that file is run on its own.
  • ruff check src/ tests/ clean; ruff format --check src/ tests/ reports 739 files already formatted.
  • mypy src/ --ignore-missing-imports — success, no issues found in 354 source files.
  • Coverage under the CI gate: 72.36%, unchanged from main.
  • CHANGELOG.md untouched — left to the release entry, as with fix(storage): bind datetimes in time comparisons so they select by value #191fix(memory): refresh content-derived fields on compress, restore, and refine #193.

Verified by

@RobertSigmundsson

MaintenanceConfig's default strategy tuple was ("prune", "merge", "enrich").
`mature` is the strategy that owns the EPISODIC to SEMANTIC transition —
ConsolidationStrategy.MATURE dispatches to _mature, which is the only place
that transition happens — so leaving it out meant a deployment on the defaults
never promoted anything.

That matters most for `smem serve`, whose `_consolidation_loop` is a plain
background task with no operation-triggered `auto_consolidate` to fall back on:
if the scheduled pass does not mature, nothing does, and the brain accumulates
episodic memories indefinitely without ever erroring.

Both the field default and the `from_dict` fallback are changed, because the
HTTP daemon rebuilds MaintenanceConfig from a dict on every reload and would
otherwise pick the old tuple straight back up. `docs/reference/config.md` is
generated from the field defaults and follows.

Order is not significant here: the engine groups strategies into
STRATEGY_TIERS, a tuple of frozensets, and runs them tier by tier rather than
in the order the config lists them. "mature" is placed between "merge" and
"enrich" for readability, nothing more.

Two assertions in tests/unit/test_scheduled_consolidation_handler.py already
pinned the old tuple and are updated; a new test asserts "mature" is present
via both the field default and the from_dict fallback, so a regression to a
non-maturing default fails loudly rather than quietly.

@acidkill acidkill left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Reviewed the full diff. Adding 'mature' to the scheduled-consolidation default fixes the silently non-maturing HTTP daemon; both the field default and the from_dict fallback are pinned by tests. Py3.11 rerun green (it was the #226 hash-seed flake).

@acidkill
acidkill merged commit a883fb1 into acidkill:main Sep 7, 2026
17 of 18 checks passed
@acidkill acidkill mentioned this pull request Sep 7, 2026
4 tasks
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.

2 participants