gabriel / muse public
feat BREAKING symlog task/symlog-phase4 #5 / 5
AI Agent gabriel · 19 days ago · Jun 28, 2026 · Diff

feat(symlog): Phase 4 — lifecycle management (SL_36–SL_45)

- muse symlog expire SYMBOL|--file FILE|--all [--expire-days N] [--dry-run] [--json] prunes journal entries older than the configured or explicit TTL - muse symlog delete SYMBOL @{N}|--all [--json] removes one entry by @{N} index or all entries atomically - muse config set symlog.expire-days N: new [symlog] config section with get/set/load/dump support mirroring the [reflog] pattern - GcResult.symlog_expired: new field; muse gc --json gains symlog_expired - _expire_all_symlogs() called by _run_gc_inner() after reflog expiry; muse gc reads symlog.expire-days config key, defaults to 90 days - 36 tests in tests/test_cmd_symlog_lifecycle.py covering SL_36–SL_45

sha256:bb5f188f4947e008edbb5acdbf076a93ebb02a8a089332b0f168bc5e473b62df sha
+76 ~24 symbols
sha256:4cc28a26896e076068e4660c8f53e365bd0926354e657f33ac29d4e4e04d57fb snapshot
+76
symbols added
~24
symbols modified
0
dead code introduced
Semantic Changes 100 symbols
~ tests/test_cmd_symlog_lifecycle.py .py 61 symbols added
+ TestSL36SingleSymbolExpire class class TestSL36SingleSymbolExpire L121–210
+ test_expire_deletes_log_file_when_all_expire method method test_expire_deletes_log_file_when_all_expire L184–196
+ test_expire_json_schema method method test_expire_json_schema L198–210
+ test_expire_keeps_recent_entries method method test_expire_keeps_recent_entries L140–171
+ test_expire_nonexistent_symbol_is_noop method method test_expire_nonexistent_symbol_is_noop L173–182
+ test_expire_removes_old_entries method method test_expire_removes_old_entries L124–138
+ TestSL37FileExpire class class TestSL37FileExpire L218–279
+ test_expire_all_symbols_in_file method method test_expire_all_symbols_in_file L221–237
+ test_expire_file_no_symlogs_is_noop method method test_expire_file_no_symlogs_is_noop L239–248
+ test_expire_file_partial_expiry method method test_expire_file_partial_expiry L250–279
+ TestSL38AllExpire class class TestSL38AllExpire L287–317
+ test_expire_all_default_ttl_keeps_recent method method test_expire_all_default_ttl_keeps_recent L305–317
+ test_expire_all_symbols method method test_expire_all_symbols L290–303
+ TestSL39DryRun class class TestSL39DryRun L325–378
+ test_dry_run_all_mode method method test_dry_run_all_mode L363–378
+ test_dry_run_does_not_write method method test_dry_run_does_not_write L328–344
+ test_dry_run_file_mode method method test_dry_run_file_mode L346–361
+ TestSL40ConfigExpireDays class class TestSL40ConfigExpireDays L386–458
+ test_config_ttl_is_used_as_default method method test_config_ttl_is_used_as_default L420–438
+ test_config_ttl_keeps_recent method method test_config_ttl_keeps_recent L440–458
+ test_invalid_value_raises method method test_invalid_value_raises L400–408
+ test_set_and_get_round_trip method method test_set_and_get_round_trip L389–398
+ test_zero_raises method method test_zero_raises L410–418
+ TestSL41DeleteIndex class class TestSL41DeleteIndex L466–524
+ test_delete_json_schema method method test_delete_json_schema L512–524
+ test_delete_last_entry_removes_file method method test_delete_last_entry_removes_file L498–510
+ test_delete_middle_entry method method test_delete_middle_entry L484–496
+ test_delete_newest_entry method method test_delete_newest_entry L469–482
+ TestSL42DeleteAll class class TestSL42DeleteAll L532–575
+ test_delete_all_deleted_equals_prior_count method method test_delete_all_deleted_equals_prior_count L564–575
+ test_delete_all_missing_log_graceful method method test_delete_all_missing_log_graceful L553–562
+ test_delete_all_removes_log_file method method test_delete_all_removes_log_file L535–551
+ TestSL43OutOfBounds class class TestSL43OutOfBounds L583–624
+ test_delete_nonexistent_symbol_exits_user_error method method test_delete_nonexistent_symbol_exits_user_error L616–624
+ test_index_error_message_contains_valid_range method method test_index_error_message_contains_valid_range L600–614
+ test_index_too_large_exits_user_error method method test_index_too_large_exits_user_error L586–598
+ TestSL44GcIntegration class class TestSL44GcIntegration L632–678
+ test_gc_expires_old_entries method method test_gc_expires_old_entries L653–664
+ test_gc_json_has_symlog_expired method method test_gc_json_has_symlog_expired L643–651
+ test_gc_keeps_recent_entries method method test_gc_keeps_recent_entries L666–678
+ test_gc_result_has_symlog_expired_field method method test_gc_result_has_symlog_expired_field L635–641
+ TestSL45Integration class class TestSL45Integration L686–778
+ _build_mixed_log method method _build_mixed_log L689–708
+ test_all_expire_deletes_log_file method method test_all_expire_deletes_log_file L746–758
+ test_gc_dry_run_does_not_write method method test_gc_dry_run_does_not_write L729–744
+ test_gc_removes_50_of_100 method method test_gc_removes_50_of_100 L710–727
+ test_gc_with_custom_symlog_ttl method method test_gc_with_custom_symlog_ttl L760–778
+ _invoke_gc function function _invoke_gc L98–113
+ _invoke_symlog function function _invoke_symlog L80–95
+ _write_entries function function _write_entries L51–77
+ ExitCode import import ExitCode L29–29
+ NULL_CONTENT_ID import import NULL_CONTENT_ID L30–30
+ annotations import import annotations L20–20
+ argparse import import argparse L22–22
+ json import import json L23–23
+ pathlib import import pathlib L24–24
+ pytest import import pytest L27–27
+ read_symlog import import read_symlog L30–30
+ symlog_path import import symlog_path L30–30
+ time import import time L25–25
+ repo function function repo L43–48
~ muse/cli/commands/gc.py .py 1 symbol added, 6 symbols modified
~ muse/cli/commands/symlog.py .py 9 symbols added, 9 symbols modified
+ _AT_INDEX_RE variable variable _AT_INDEX_RE L500–500
+ _DEFAULT_SYMLOG_EXPIRE_DAYS variable variable _DEFAULT_SYMLOG_EXPIRE_DAYS L501–501
+ _DeleteJson class class _DeleteJson L146–149
+ _ExpireJson class class _ExpireJson L139–143
+ delete_symlog_entry import import delete_symlog_entry L79–79
+ expire_symlog import import expire_symlog L79–79
+ re import import re L72–72
+ run_delete function function run_delete L662–750
+ run_expire function function run_expire L557–654
~ run
~ muse/cli/config.py .py 1 symbol added, 6 symbols modified
~ muse/core/gc.py .py 4 symbols added, 3 symbols modified
+ _DEFAULT_SYMLOG_EXPIRE_DAYS variable variable _DEFAULT_SYMLOG_EXPIRE_DAYS L462–462
+ _expire_all_symlogs function function _expire_all_symlogs L686–703
+ expire_symlog import import expire_symlog L84–84
+ list_symlog_symbols import import list_symlog_symbols L84–84
~ run_gc

0 comments

No comments yet. Be the first to start the discussion.

To add a comment, use the Muse CLI: muse hub commit comment sha256:bb5f188f4947e008edbb5acdbf076a93ebb02a8a089332b0f168bc5e473b62df --body "your comment"