Mirror the warm→hot budget-fallback pattern for the cold→warm promotion
path in ContextTierService.promote(). When _enforce_warm_capacity()
evicts the just-promoted fragment (because its last_accessed timestamp
predates all existing warm entries), restore it with _touch() so it
carries a current timestamp and is not immediately re-evicted.
Without this guard the fragment is silently lost from all stores while
the caller receives a stale handle with tier=WARM — identical to the
data-loss scenario the hot-budget fallback was introduced to prevent.
ISSUES CLOSED: #9663
- Remove unused conflicting _DEFAULT_* constants that conflicted with
canonical defaults in context_tier_settings.py (which serves as the
sole source of truth for budget/setting defaults).
- Add _enforce_warm_capacity() to enforce max_decisions_warm limit on
warm tier after cold→warm promotion and hot-budget-fallback restore,
preventing silent over-capacity data accumulation.
- Return deep copies (model_copy) from get_all_fragments() and
get_hot_fragments() to prevent callers from mutating internal fragment
state while the service holds its RLock under concurrent plan execution.
- Rename _COLD_SUMMARY_MAX_CHARS → _default_summarisation_max_chars for
consistent snake_case naming throughout the module.
Fixes: PR #9663