legacy-elimination¶
Context¶
Stogger’s codebase carries 30+ legacy artifacts from its evolution: dead code from absorbed packages, backwards-compatibility keys from fc-agent inheritance, defensive exception handling that violates fail-loudly principles, stale documentation referencing non-existent modules, and spec test lifecycle debt. CODEX Article 4 mandates: BREAK EVERYTHING NOW — no migration paths, no deprecation periods, no fallbacks.
Decisions¶
dead-code-removal¶
Context¶
Dead code from absorbed packages and abandoned features litters the codebase. JournalLoggerFactory stub in core.py was superseded when stogger-systemd was absorbed as src/stogger/systemd.py. _regexes.py has no production consumer — only tests verify its existence. Dead fields show_logger_brackets and show_pid in ConsoleFileRenderer were explicitly documented as dead by ADR format-config-extension. A bare sys.stdout.isatty() call in ConsoleFileRenderer.__init__ discards its result.
Decision¶
Remove all dead code:
Delete
_regexes.pymodule entirelyDelete
JournalLoggerFactorystub class from core.pyDelete
show_logger_bracketsandshow_piddead fields fromConsoleFileRenderer.__init__Delete bare
sys.stdout.isatty()call fromConsoleFileRenderer.__init__Remove
JournalLoggerFactoryexport from__init__.pyUpdate any tests that verify dead code existence
Alternatives¶
a. Keep dead code “just in case” — violates Article 4, accumulates maintenance burden b. Move to archive branch — code archeology is git’s job, not the codebase’s
Consequences¶
~120 lines removed from production code. Any external consumer of JournalLoggerFactory (unlikely — it returns None) gets an ImportError, which is correct behavior.
broad-exception-cleanup¶
Context¶
Five catch-all except Exception blocks silently suppress failures. init_early_logging swallows all startup errors as debug messages. MultiRenderer.__call__ and MultiOptimisticLogger.msg catch all renderer failures silently. _load_pyproject_config has a redundant (tomllib.TOMLDecodeError, Exception) tuple. _check_test_dependencies defers warnings to process exit via atexit.
Decision¶
Replace broad exception handling with let-it-crash or targeted catches:
init_early_logging: remove the try/except entirely — let startup failures propagateMultiRenderer.__call__: keep try/except but re-raise asRuntimeErrorwith context — renderer failures must be visibleMultiOptimisticLogger.msg: same as MultiRenderer — re-raise with context_load_pyproject_config: catch onlyFileNotFoundErrorandtomllib.TOMLDecodeError— remove bareException_check_test_dependencies/_PENDING_WARNINGS/atexit: remove deferred warning system entirely — emit warnings immediately or remove the feature
Alternatives¶
a. Keep silent catches for “logging must not crash the app” — violates Article 5, hides real bugs b. Log at error level instead of debug — better but still hides the failure from the caller
Consequences¶
Failures surface immediately at the call site. Any code depending on silent error suppression will break, which is the intended outcome. Renderer errors become visible in CI and production logs.
backwards-compat-purge¶
Context¶
The bare "output" key in KEYS_TO_SKIP_IN_JOURNAL_MESSAGE is documented as retained “for backward compatibility” — it’s a bug from “original fc-agent code” with the actual key being "_output". The log_to_stdlib processor exists solely for “Legacy code that reads from stdlib logging handlers.” Two version management systems coexist in pyproject.toml: hatch-vcs (active) and bumpversion (redundant). scripts/release.py references stogger-systemd (absorbed into main package) and pytest-stogger (not in workspace).
Decision¶
Remove all backwards-compatibility artifacts:
Remove bare
"output"fromKEYS_TO_SKIP_IN_JOURNAL_MESSAGERemove
log_to_stdlibprocessor function entirelyRemove
[tool.bumpversion]section and[[tool.bumpversion.files]]from pyproject.tomlRemove
stogger-systemdandpytest-stoggerfromscripts/release.pyPROJECTS dictRemove
scripts/release.pydocstring references to these projects
Alternatives¶
a. Keep "output" key “just in case” — perpetuates a known bug
b. Keep log_to_stdlib for gradual migration — violates Article 4
c. Keep bumpversion alongside hatch-vcs — redundant configuration is confusing
Consequences¶
Breaking changes for any consumer using bare "output" key or log_to_stdlib processor. Both are documented as legacy/deprecated already. Version management consolidated to hatch-vcs only. Release script only references workspace members.
vulture-whitelist-cleanup¶
Context¶
.vulture_whitelist.py has 168 lines, ~140 of which reference code that no longer exists: eliot integration, CLI commands (tools_generate_service, tools_review, etc.), i18n functions, interactive transformer, web dashboard, 18 PyDoit task functions, ~30 Sphinx config variables. The file header lists categories that are stale.
Decision¶
Remove all whitelist entries for non-existent code. Keep only entries that reference actual symbols in the current codebase. Rewrite the module docstring to reflect current categories. If no legitimate entries remain, delete the file entirely and remove the vulture config from pyproject.toml.
Alternatives¶
a. Keep stale entries as “documentation” — vulture whitelists are not documentation b. Partial cleanup — leaves misleading entries that suggest features exist
Consequences¶
Clean whitelist that accurately reflects the codebase. Vulture continues to catch dead code without false positives from ghost entries.
stale-documentation-fix¶
Context¶
CONVENTIONS.md references mypy (project uses ty), and lists non-existent components (stoggertools.cli, stogger.advanced_assistant, stogger.i18n). docs/dev/type_checking_guide.md shows wrong import path (stogger_systemd instead of stogger.systemd). All 4 ADRs have a placeholder HTML comment about pending tests in ## Verified By. pyproject.toml has a commented-out infrastructure_files line that should have been deleted per ADR stogger-self-logging.
Decision¶
Fix all stale documentation:
CONVENTIONS.md: replace mypy reference with ty, remove references to non-existent componentsdocs/dev/type_checking_guide.md: fix import path fromstogger_systemdtostogger.systemdAll ADRs: remove the pending-tests placeholder comments from
## Verified Bysectionspyproject.toml: remove commented-outinfrastructure_filesline
Alternatives¶
a. Leave documentation stale — misleading for contributors and users b. Only fix ADRs — leaves CONVENTIONS.md and type_checking_guide wrong
Consequences¶
Documentation matches reality. ADR Verified By sections are empty (honest) instead of containing placeholder promises.
spec-test-lifecycle-cleanup¶
Context¶
Three impl_spec test files totaling 843 lines should have been garbage-collected after passing. tests/impl_spec/test_logging_decorators_docs.py (143 lines) — impl spec logging-decorators-docs is fully verified. tests/impl_spec/test_format_config_extension.py (373 lines) — ADR format-config-extension is implemented. tests/impl_spec/test_postgres_target.py (327 lines) — ADR postgres-target is implemented. These tests pass without xfail markers but remain in the tree.
Decision¶
Delete all three impl_spec test files. Their purpose (spec validation before implementation) is complete. Permanent tests in tests/test_core.py, tests/test_config.py, and tests/test_decorators.py cover the functionality.
Alternatives¶
a. Keep as “extra coverage” — redundant, confuses test purpose, 843 lines of maintenance burden b. Move to permanent test files — tests already exist in natural locations
Consequences¶
843 lines of temporary test code removed. Test tree clean — only permanent tests remain.
colorama-availability-check¶
Context¶
_colors.py has a runtime check for colorama availability (if sys.stdout.isatty() and colorama), falling back to empty strings when colorama is missing. But colorama is a hard dependency in pyproject.toml (colorama>=0.4.6). The fallback branch is unreachable in a properly installed environment.
Decision¶
Remove the colorama availability check. Import colorama directly without fallback. The empty-string fallback is dead code.
Alternatives¶
a. Keep the check for “flexibility” — colorama is a hard dependency, flexibility is misleading b. Make colorama optional — contradicts project’s design decision
Consequences¶
Simpler code. If colorama is somehow missing, the ImportError is immediate and clear rather than silently producing colorless output.
optional-import-simplification¶
Context¶
The systemd dynamic import in core.py catches ImportError for stogger.systemd, but stogger.systemd is now a built-in module (not an external package). The ImportError path cannot fire in the current codebase. The postgres dynamic import catches ImportError legitimately (optional dependency) but uses import_error=True which is a misleading key-value.
Decision¶
Systemd import: replace dynamic import with direct
from stogger.systemd import get_journal_logger_factory— remove the try/except ImportError entirelyPostgres import: keep the try/except (legitimate optional dependency) but fix
import_error=Trueto a more meaningful debug message
Alternatives¶
a. Keep both dynamic imports “for consistency” — the systemd one masks a design change that already happened b. Remove postgres ImportError handling too — breaks users without stogger-postgres installed
Consequences¶
Systemd import is direct and fails at module level if broken (correct behavior). Postgres import remains defensive but with honest debug output.