fix(cli)!: rename mm session start --json key stale_ended → auto_ended#545
Merged
memtomem merged 2 commits intorelease/v0.1.33from Apr 29, 2026
Merged
Conversation
The JSON list returned by `mm session start --json` carries UUIDs from two distinct paths: cutoff-based stale cleanup driven by `--auto-end-stale`, and the cross-agent forced-end inside `--idempotent` when the active session belongs to a different `--agent-id`. The previous key `stale_ended` only describes the first; cross-agent ends are not stale, just superseded. The DB metadata already disambiguates them via `metadata.reason` (`stale` vs `cross_agent`) — this commit aligns the JSON key with the metadata's existing `auto_ended` flag so the CLI surface and the storage record use one vocabulary. Drops the misleading "stale" word from the text-mode print line for the same reason. The shape only shipped post-v0.1.32 (PR #543, b8a5673) and never went out in a tagged release, so no released hook caller depends on the old key. Followup item 2 from RFC `memtomem-docs#24` (per-entry `reason` shape: flat vs split vs dict-enriched) stays deferred — that decision needs a distribution measurement on `sessions.metadata.reason` after a few weeks of real hook usage. The per-row `reason` is already on disk, so no telemetry plumbing is required for that future analysis. Co-Authored-By: Claude <[email protected]>
Per PR review: ``mm session start`` text mode previously printed ``Auto-ended N session(s)`` after the rename, dropping the "stale" hint that the prior wording carried. JSON consumers don't lose anything (``sessions.metadata.reason`` carries the per-row split), but a human running the command by hand can't tell whether the auto-ends came from cutoff age or from cross-agent forced-ends. Track per-reason counters at the two append sites — both code paths already know which reason they're handling — and emit a ``(N stale, M cross-agent)`` suffix when either is non-zero. The JSON shape (flat list of UUIDs) is untouched so the existing ``test_json_output_shape`` pin still holds. New test ``test_text_mode_breakdown_by_reason`` exercises both paths firing in the same call and pins the two count fragments, since this is the only place the per-reason split is now surfaced without going through SQL. Co-Authored-By: Claude <[email protected]>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
mm session start --jsonoutput keystale_ended→auto_endedso the CLI surface matches the DB metadata's existingauto_endedflag and stops calling cross-agent forced-ends "stale".--auto-end-stale) and cross-agent forced-end inside--idempotent. Per-row distinction stays onsessions.metadata.reason(staleorcross_agent).Auto-ended N session(s) (X stale, Y cross-agent). Pinned by a newtest_text_mode_breakdown_by_reason.Why this is safe to land as-is — base retargeted to
release/v0.1.33The
stale_endedshape only appeared onmainafter v0.1.32 (PR #543, b8a5673, 2026-04-29) and was never tagged into a published PyPI release. Base retargeted frommaintorelease/v0.1.33so the rename ships as part of the v0.1.33 cut —stale_endedtherefore never reaches PyPI and there is no published API to break. Plugin's ownhooks.jsoncalls the CLI in text mode, not--json, so the rename has zero impact on the shipped Claude Code SessionStart recipe.Followup tracker
RFC
memtomem-docs#24listed two open questions deferred to "telemetry-then-decide":[{id, reason}]). Needs a distribution measurement onsessions.metadata.reasonafter a few weeks of hook usage to know whether cross-agent ends are common enough to justify schema enrichment. The reason field is already persisted on every auto-end (session_cmd.py:215, 245), so no extra telemetry plumbing is required when the data window is up.Review polish addressed
b511dcfadds per-reason counters at the two append sites and renders(N stale, M cross-agent)whenever either fired. JSON shape unchanged.Test plan
uv run pytest packages/memtomem/tests/test_session_cli.py -m "not ollama"— 27 passed (26 prior + new breakdown test).uv run pytest packages/memtomem/tests -m "not ollama" -k "session or hook"— all pass.uv run ruff checkanduv run ruff format --checkclean.mm session start --idempotent --auto-end-stale 24h --agent-id claude-code --jsonreturnsauto_endedkey.🤖 Generated with Claude Code