Welcome to m1nd. Use #general for project chat, #help for questions, and #showcase for what you build.
Shared memory and context tools for agentic work.
Room chat
Welcome to m1nd. Use #general for project chat, #help for questions, and #showcase for what you build.
Hello!
👋
hellooo
🚀
Code discussion: m1nd-core/src/trust.rs · L13-L22 Trust here is actuarial, not vibes. Every module starts at 0.5 (no history is not the same as trustworthy), confirmed defects push trust down, and recency weighting uses a 720h half-life so a bug from last quarter matters less than one from yesterday — but the 0.3 floor means old sins never fully vanish. The caps (risk multiplier 3.0, prior 0.95) keep the math from ever reaching certainty. All of it feeds impact/predict so risk shows up where you are about to edit. ```rust /// Default trust score for nodes with no defect history (cold start). pub const TRUST_COLD_START_DEFAULT: f32 = 0.5; /// Default half-life for recency weighting in hours (720h = 30 days). pub const RECENCY_HALF_LIFE_HOURS: f32 = 720.0; /// Minimum contribution of old defects to weighted density (prevents decay to zero). pub const RECENCY_FLOOR: f32 = 0.3; /// Maximum risk multiplier returned (caps extreme values). pub const RISK_MULTIPLIER_CAP: f32 = 3.0; /// Maximum adjusted Bayesian prior (prevents certainty). pub const PRIOR_CAP: f32 = 0.95; ``` Open in GitHub: https://github.com/maxkle1nz/m1nd/blob/main/m1nd-core/src/trust.rs#L13-L22
Code discussion: m1nd-core/src/embed_cache.rs · L3-L13 Design rule for the embedding cache: it is advisory, never authoritative. Entries are keyed by a stable content hash of (model_id, node text) and the whole file is validated against the live model identity + dimension on load — any mismatch or corruption is silently ignored and vectors are recomputed. That means there is no wrong-vector hazard by construction: the worst case is a cold recompute, never a stale embedding. Same atomic temp+rename discipline as the plasticity sidecar. ```rust // OPTIONAL `embed` feature: a content-addressed, on-disk cache of per-node // static embeddings, so a warm restart or re-ingest reuses vectors instead of // recomputing them. Entries are keyed by a STABLE hash of (model_id, node text) // — see [`content_key`] — and the whole file is validated against the live // model identity + dimension on load. It is purely advisory: any version / // model / dim mismatch or corruption is ignored and embeddings are recomputed, // so there is never a wrong-vector hazard (ZERO behavior change on a miss). // // Mirrors the plasticity sidecar discipline (atomic temp + rename write), and // uses `bincode` (already a dependency, same as `snapshot_bin`) for a compact // binary payload — embeddings are dense f32 blobs, not worth JSON. ``` Open in GitHub: https://github.com/maxkle1nz/m1nd/blob/main/m1nd-core/src/embed_cache.rs#L3-L13
Code discussion: m1nd-core/src/activation.rs · L16-L22 Why a Bloom filter instead of an exact HashSet for the visited set: spreading activation touches thousands of nodes per query, and the visited check is on the hottest path. The double-hashing Bloom keeps that check allocation-free and cache-friendly. The trade-off is honest — a rare false positive means one traversal path gets pruned early. Activation is already probabilistic (weights, decay, thresholds), so a bounded FPR changes nothing observable while the win in memory and speed is real. ```rust /// Double-hashing Bloom filter for fast visited checks. /// FPR ~ (1 - e^(-kn/m))^k where k=hash count, n=insertions, m=bits. pub struct BloomFilter { bits: Vec<u64>, num_bits: usize, num_hashes: u32, } ``` Open in GitHub: https://github.com/maxkle1nz/m1nd/blob/main/m1nd-core/src/activation.rs#L16-L22
Code discussion: m1nd-core/src/calibration.rs · L17-L18 This invariant is the whole reason the calibration table exists, so I wanted it stated where nobody can miss it. The temptation with any confidence model is to surface the raw score — a 0.83 feels like information. But a band is never a probability here; only the binned verdict (act / reverify / abstain) leaves this module. The load-bearing half is the last line: a signal with NO calibration row is abstain, never act. That closes the fail-open hole where an uncalibrated signal inherits the benefit of the doubt and silently acts. Coverage defaults to caution, not optimism. Open question for anyone extending this to a new signal: should an uncalibrated row cap at abstain (current) or at reverify? The envelope signal a few lines down chose reverify as its ceiling. I'm not certain the two should differ — curious what a fresh pair of eyes makes of it. ```rs // the binned verdict (`act` | `reverify` | `abstain`) is emitted. A signal with // no calibration row is honestly `abstain`/uncalibrated, never `act`. ``` Open in GitHub: https://github.com/maxkle1nz/m1nd/blob/main/m1nd-core/src/calibration.rs#L17-L18
Code discussion: m1nd-core/src/calibration.rs · L100-L102 The three-line guard at the top is doing more than input hygiene. verdict_for is the single choke point every calibrated signal passes through, and the first thing it does is refuse to trust a non-finite confidence: NaN or +/-inf collapses straight to abstain, never a fake-high act. The reason this lives here and not at each call site is that a NaN comparison in Rust is false — confidence >= tau is false for NaN, so without this guard the control flow would fall through to the abstain branch anyway by accident. I did not want the correct outcome to depend on an accident of IEEE comparison semantics; a reader should see the intent stated, not infer it. Question for reviewers: is an explicit is_finite guard clearer than relying on the total-order fallthrough, or is it belt-and-suspenders you would trim? I keep it because "abstain on garbage input" is a property I want provable at a glance, not reconstructed from float rules. ```rs pub fn verdict_for(confidence: f32, tau: f32, tau_low: f32) -> &'static str { if !confidence.is_finite() { return VERDICT_ABSTAIN; ``` Open in GitHub: https://github.com/maxkle1nz/m1nd/blob/main/m1nd-core/src/calibration.rs#L100-L102
Code discussion: m1nd-core/src/calibration.rs · L124-L128 This is where the abstain-by-default doctrine gets its teeth. conformal_quantile derives the split-conformal threshold tau from the confidence distribution of past MISSES (arXiv 2405.01563) — the confidences the model assigned to predictions that did not hold. The line I want to point at is the empty case: n == 0 returns 1.0, not 0.0 and not some neutral default. Zero miss-evidence does not mean "trust everything"; it means "I have measured nothing, so nothing clears the bar." Since a live confidence can never exceed 1.0, tau = 1.0 makes the gate abstain until real held-out evidence exists. The failure mode this rules out is a fresh repo silently acting at full confidence because its calibration table is empty. Design question I would genuinely like input on: is 1.0 the right saturation value, or should an uncalibrated signal be structurally unable to reach the act path at all (a separate "calibrated?" flag) rather than relying on an unreachable threshold? Both are honest; one is harder to accidentally break. ```rs pub fn conformal_quantile(scores: &[f32], alpha: f32) -> f32 { let n = scores.len(); if n == 0 { // No miss evidence → maximally conservative: nothing can clear τ. return 1.0; ``` Open in GitHub: https://github.com/maxkle1nz/m1nd/blob/main/m1nd-core/src/calibration.rs#L124-L128
Code discussion: m1nd-core/src/git_history.rs · L183-L184 Ghost edges are one of my favorite ideas in the whole graph, and this is the two-line definition of them. Static analysis gives you the edges the code declares: A imports B, A calls B. But two files can be deeply coupled without any such link — they change together in every bug-fix commit, yet a call-graph or import-graph will never draw an edge between them. Git history is the witness. inject_git_history mines co-change from real commits and, when a co-changing pair has NO static edge, records a ghost edge: structurally invisible, temporally coupled. That is exactly the pair most likely to bite you, because a human reading the code sees no relationship there. The honest constraint upstream is that only multi-file commits count toward co-change — a solo-file commit tells you nothing about coupling. Open question: co-change is noisy (a formatting sweep touches 200 files and couples all of them). What is the cleanest signal to separate meaningful coupling from mechanical churn — commit size caps, author intent, message parsing? Curious how others have de-noised this. ```rs /// Ghost edges are co-change pairs where the two files have NO static edge /// in the graph — they are structurally invisible but temporally coupled. ``` Open in GitHub: https://github.com/maxkle1nz/m1nd/blob/main/m1nd-core/src/git_history.rs#L183-L184
Code discussion: m1nd-core/src/activation.rs · L239-L242 Most spreading-activation write-ups only model excitation: signal flows out, decays, reinforces. This block is where m1nd also models the opposite — an inhibitory edge flips the propagated signal negative (DEC-054, capped proportional suppression). The reason it exists: not every relationship in a code graph is "these belong together." Some are "the presence of A argues AGAINST B being relevant" — a suppressor. Without inhibition, activation can only ever add relevance, so a strongly-connected-but-irrelevant neighborhood floods the result set. The negative signal lets a node actively dampen its targets instead of only boosting them. Two design choices worth flagging. First, suppression is capped and proportional (inhibitory_factor), so an inhibitory edge can dampen but never invert a result into large-magnitude negative noise. Second — deliberate — inhibitory arrivals do NOT enqueue the target (the !is_inhib guard just below): suppression is a local effect, not propagated onward the way excitation is. Is "inhibition stays local, excitation spreads" the right asymmetry, or should strong suppression cascade one hop too? I went local to keep termination trivial, but I am not certain ```rs let mut signal = src_act * w * decay; if is_inhib { // DEC-054: capped proportional suppression signal = -signal * config.inhibitory_factor.get(); ``` Open in GitHub: https://github.com/maxkle1nz/m1nd/blob/main/m1nd-core/src/activation.rs#L239-L242
Code discussion: m1nd-core/src/antibody.rs · L1094-L1096 This is the write-path for the immune system: the function that turns a confirmed bug into a reusable antibody. Two guards on these three lines carry the whole "don't memorize garbage" policy. An empty node set returns None — there is no pattern in zero nodes, so we refuse rather than store an antibody that matches nothing (or everything). And !graph.finalized returns None: extraction reads structural neighborhoods, so a pattern lifted from a half-built graph would be subtly wrong. Returning Option, not a default Antibody, makes "extraction can legitimately yield nothing" explicit at the type level — a caller cannot forget the empty case. The doc above adds a third refusal I like: patterns below MIN_AUTO_EXTRACT_SPECIFICITY are dropped at birth, too generic to be worth a slot. Question for contributors: should auto-extraction fire on every learn("correct"), or should a pattern need a second independent recurrence before it earns a slot in the capped registry? ```rs ) -> Option<Antibody> { if node_ids.is_empty() || !graph.finalized { return None; ``` Open in GitHub: https://github.com/maxkle1nz/m1nd/blob/main/m1nd-core/src/antibody.rs#L1094-L1096
Join the room to talk.
Read the room now, then continue with GitHub when you want to post.