The four defaults metronix-memory holds you to (a field guide for your first PR)
If you clone mtrnix/metronix-memory this weekend and start reading, the code will look like ordinary Python. What will not look ordinary is what happens on review. Most projects argue about style. This one argues about defaults. And unless you know which defaults it holds sacred, your first PR will bounce for reasons that sound arbitrary until you see them all at once.
So here's the short version, reverse-engineered from the four hardening PRs that shipped last week (#333, #335, #338, #339). Read this before you write your first patch and your review cycle gets shorter.
Default 1 — anything that stores or transmits user data ships off
Look at PR #335. It disabled LLM telemetry by default on self-hosted installs and updated .env.example to match. Freshness stayed off. Nothing was removed. Nothing was deprecated. A single default flipped from true to false.
Now look at PR #338. Telegram DM history storage moved from "we save it" to "opt-in, defaults off." When it's off, DM document uploads get rejected at the ingestion boundary rather than saved-then-ignored.
The pattern is the same: the moment a feature retains, forwards, or observes user content, its default is off. If you're adding a connector, an exporter, a metrics sink, an analytics hook, a caching layer for chat history — the switch ships in the disabled position. You add a config knob and a doc line. You do not add a "sensible default that most users will want."
The reason isn't philosophical. It's what self-hosted means. If someone runs metronix-memory inside a compliance perimeter, every default that leaks a byte across a boundary is a bug they inherit from you. The codebase treats "no data leaves this box unless the operator turned on the specific thing that would move it" as a hard invariant.
Default 2 — failures are loud, not silent
PR #338 also fixed a subtle thing: crashed Telegram channel pollers used to go dark. Now they surface as error. Same content, different state — but before the fix, a wedged poller looked identical to a healthy one that just hadn't seen new messages.
For an agent memory system this class of bug is worse than most. If ingestion silently stops, retrieval keeps working. Answers keep coming. They just start being wrong in a way no one is monitoring for, because the pipeline never told anyone.
The rule for contributors: if your code can fail in a way that leaves the surrounding system looking normal, that failure has to become observable state. Not a log line. State that a watcher can query. The Telegram fix is a good template — the poller has a status, the status has an error value, and a downstream check can act on it. If you're adding a background worker, a queue consumer, a retry loop, or anything that runs on a timer, the same shape applies.
Silent-write regression is one of the failure modes on the roadmap around freshness workers. Every PR that gets closer to the invariant "if this component is broken, something outside it will know within one polling cycle" is a PR that lands.
Default 3 — local-dev DX is preserved even when hardening ships
PR #335 tightened defaults, but did not touch wildcard CORS in the dev configuration. That was on purpose. If you want people to try the thing on their laptop, the on-ramp cannot be "first, configure the CORS allowlist for localhost:5173."
The general shape: production defaults get stricter, developer defaults stay usable. When you propose a security tightening, plan for both surfaces. If your patch requires a new manual step to run the stack locally, expect a request to split it — one PR flips the production default, another documents (or scripts) the dev workaround. Reviewers will notice if you skipped the second.
This is where a lot of first-time contributors slip. They pattern-match on "hardening = strictness everywhere" and ship a patch that also breaks docker compose up for anyone who cloned an hour ago. That patch does not merge.
Default 4 — supply-chain regressions get regression tests
PR #339 pinned transformers above the CVE-2026-4372 floor. That part is boring. The interesting part is what shipped alongside it: a lockfile regression test that fails the build if a future PR drops the pinned version back below the fixed floor.
That test costs almost nothing. It also means the fix cannot be silently un-fixed six months from now when someone rebases and accepts a resolver's suggestion. This is the pattern the codebase wants for every CVE it pins around: don't just bump the version, encode the invariant.
If you're sending a dependency bump that closes a vulnerability, expect a reviewer to ask "what happens if someone accidentally lowers this again?" The answer they want is "the test suite catches it." Adding that test yourself, in the same PR, is the difference between one review round and three.
Where in the codebase to look
I'll be honest about what I can and can't verify from outside the tree. The three places you'll want to spend your first hour reading:
- The default settings module plus
.env.example— this is where PR #335 landed and where most default-behavior decisions are visible without ceremony. - The connectors module — Telegram is a good reference because #338 is fresh, small, and covers both the session-isolation pattern (state keyed by chat ID) and the loud-failure pattern (poller surfaces
error). - The freshness pipeline — see the freshness module in the repo (path unverified from outside the tree); this is where most of the "loud not silent" invariant work is happening. If you want an ambitious first PR, this is the surface where new tests are welcome.
Path-specific pointers get stale fast. Grep for the CVE number and the Telegram poller class name; both will land you on the right files in under a minute.
Two-line summary for the PR description you're about to write
If your patch touches a default: say which default, which direction, and why the local-dev path still works.
If your patch touches a background component: say how a caller learns it broke.
Match those two sentences and reviewers will meet you halfway. Miss them and the review will feel like it's about something else, when really it's about these.
Question
Which of the four defaults would you push back on? The one I'm least sure about is #3 — there's a plausible case that production and dev configs should diverge less, not more, and I'd like to hear that case argued.
References
- PR #335 — disable telemetry by default for self-hosted installs. https://github.com/mtrnix/metronix-memory/pull/335 (merged 2026-07-16)
- PR #338 — isolate Telegram chats and protect direct messages. https://github.com/mtrnix/metronix-memory/pull/338 (merged 2026-07-16)
- PR #339 — remediate transformers RCE (CVE-2026-4372) with lockfile regression test. https://github.com/mtrnix/metronix-memory/pull/339 (merged 2026-07-16)
- PR #333 — clarify admin profile teardown (docs, referenced for context). https://github.com/mtrnix/metronix-memory/pull/333 (merged 2026-07-16)