From 627bd97f9c49672234a4ed68c6c627e4becbebf8 Mon Sep 17 00:00:00 2001 From: macanderson Date: Sun, 26 Jul 2026 15:38:05 -0700 Subject: [PATCH 1/2] fix(ci): drop the obsolete main.rs baseline entry that is failing main MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `main` is red. `scripts/check-file-size.sh` rejects a baseline entry for a file that no longer needs one — "an exemption must not outlive the problem it covered" — and `stella-cli/src/main.rs` is now 1421 lines with a 1816 ceiling still on the books. This is an interaction between two PRs that were in flight at the same time, not a mistake in either. #733 moved the storage/scripts/graph commands out of main.rs, took it to 1337, and *deleted* its baseline entry because the file no longer crossed the limit. #735 landed separately, grew main.rs back to 1421, and carried a baseline entry for it. Both were individually correct; together they produce a file that is under the limit and exempted from it, which the ratchet treats as an error by design. Dropping the entry is the fix the script itself prescribes. main.rs stays covered by the ordinary 1500-line limit with 79 lines of headroom. check-file-size: OK — 456 Rust files, none over 1500 lines except 27 grandfathered (none grew). --- scripts/file-size-baseline.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/scripts/file-size-baseline.txt b/scripts/file-size-baseline.txt index 1e9f093a..e7ed940e 100644 --- a/scripts/file-size-baseline.txt +++ b/scripts/file-size-baseline.txt @@ -11,7 +11,6 @@ 2224 stella-cli/src/agent.rs 1623 stella-cli/src/candidate_ws.rs 4592 stella-cli/src/command_deck.rs -1816 stella-cli/src/main.rs 2095 stella-core/src/bus.rs 2258 stella-core/src/driver.rs 2819 stella-core/src/driver/tests.rs From 68ebcc9a6e1d176b01fccf2c094c47c3b1b7a2e6 Mon Sep 17 00:00:00 2001 From: macanderson Date: Sun, 26 Jul 2026 15:45:58 -0700 Subject: [PATCH 2/2] =?UTF-8?q?fix(cli):=20repair=20main=20=E2=80=94=20a?= =?UTF-8?q?=20duplicate=20MemoryCmd=20left=20the=20tree=20not=20compiling?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `main` does not build. `cargo check -p stella-cli` fails with nine E0308s: "`MemoryCmd` and `memory_cmd::MemoryCmd` have similar names, but are actually distinct types". Cause: two PRs that each merged cleanly and are individually correct. #733 *moved* `MemoryCmd` into `memory_cmd.rs` to get `main.rs` under its size ratchet. #735 was cut from a `main` that predated that move, so it carried its own copy of the enum and added two new variants — `Compact` and `Index` — to that copy. Git merged both without a textual conflict, and the result declares the enum twice: `Command::Memory` holds a `memory_cmd::MemoryCmd`, while the dispatch arms match on the stale `crate::MemoryCmd`. This is the failure mode a textual merge is worst at: neither side touched the same lines, so nothing conflicted, and the incompatibility is a type error two files away from either change. Fix, in the direction #733 intended: - Move #735's `Compact` and `Index` variants onto `memory_cmd::MemoryCmd`, doc comments intact, with their arg types qualified through `crate::`. - Delete the stale duplicate from `main.rs`. - Qualify the dispatch arms. Also drops the obsolete `main.rs` baseline entry, which is what CI reported first: #733 deleted it when the file fell to 1337 lines, #735 re-added it at 1816, and the file is now 1421 — under the limit and exempted from it, which the ratchet rejects by design. That check masked the compile error, because file-size runs before clippy and exits first. Verified beyond the build: `stella memory --help` lists all nine subcommands, so #735's `compact` and `index` survive the move. `make gate` green: exit 0, 3670 tests, check-file-size OK. --- stella-cli/src/main.rs | 102 ++++------------------------------- stella-cli/src/memory_cmd.rs | 16 ++++++ 2 files changed, 27 insertions(+), 91 deletions(-) diff --git a/stella-cli/src/main.rs b/stella-cli/src/main.rs index 3e4542e2..e7cf3bd5 100644 --- a/stella-cli/src/main.rs +++ b/stella-cli/src/main.rs @@ -799,88 +799,6 @@ pub enum McpCmd { Usage, } -/// `stella memory` subcommands — the inspection and promotion surface of the -/// memory-citation loop (agents cite the memories that informed a turn via -/// the `cite_memory` tool; the citations aggregate into the eligibility gate -/// `promote` enforces). -#[derive(Subcommand)] -enum MemoryCmd { - /// List memories ranked by citation count, with average usefulness, - /// truthfulness rate, and rule-promotion eligibility - List { - /// Output format: table (aligned) or json - #[arg(long, value_enum, default_value = "table")] - format: memory_cmd::MemoryFormat, - }, - /// Promote an eligible memory to a project rule at - /// `.stella/rules/.md`. Eligibility is strict: cited successfully - /// MORE THAN 10 consecutive times since its last negative remark — one - /// negative citation resets the count until it is re-earned. - Promote { - /// The memory's stable id (nod_…) as shown by `stella memory list` - id: String, - }, - /// Re-validate old memories against the current codebase (Proposal 5). - /// Scans each memory for file-path anchors (e.g. `stella-cli/src/agent.rs`), - /// checks whether those paths still exist, and flags stale ones. A stale - /// memory is one whose referenced path no longer exists — a strong signal - /// the memory is about refactored-away code and may mislead. - Validate, - /// Forget a memory: stop it steering the agent, and stop the reflection - /// loop re-learning it. Reversible with `stella memory restore `. - /// - /// This is a tombstone, not a delete. The reflection loop re-mines - /// paraphrases of lessons it has already learned, so removing the row - /// alone does not hold — the tombstone also suppresses restatements at - /// the point new lessons are recorded and at the point the log is mined - /// into skills. - Forget { - /// The memory's stable id (nod_…) as shown by `stella memory list` - id: String, - /// Optional note on why, shown by `stella memory forgotten` - #[arg(long, default_value = "")] - reason: String, - }, - /// Rewrite a memory in place, as a new revision of the same memory. - /// - /// The old text becomes history rather than a competitor: one live record, - /// the same id, and recall stops serving the words you replaced. Before - /// memories had a lineage, changing one meant writing a second memory and - /// leaving the first live — both citable, with nothing to say which was - /// current. - Edit { - /// The memory's stable id (nod_…) as shown by `stella memory list` - id: String, - /// The replacement text - text: String, - }, - /// Lift a tombstone written by `stella memory forget`, letting the memory - /// be recalled again and be re-learnable. - Restore { - /// The memory's stable id (nod_…) as shown by `stella memory forgotten` - id: String, - }, - /// List the tombstones in this workspace — what was forgotten, when, and - /// why. - Forgotten, - /// Reclaim space in .stella/private/context.db by dropping derived index - /// rows whose owner is already gone: embedding vectors no memory, node or - /// episode points at (every `memory edit` strands one), and domain tags - /// pointing at rows that no longer exist. - /// - /// Memories, episodes, facts and forget tombstones are never touched — - /// point-in-time queries answer identically before and after. - Compact(memory_compact::CompactArgs), - /// Build the approximate-similarity (IVF) index recall can use instead of - /// scoring every stored vector on every turn. - /// - /// Opt-in twice over: this builds it, and `context.retrieval.ann_enabled` - /// in settings.json is what lets a recall use it. An approximate index - /// considers a subset of the corpus, so it can miss a frame the exact scan - /// would have found — which is why neither half is on by default. - Index(memory_index::IndexArgs), -} - /// NUL boundaries prevent LLVM's string pooling from adjoining identifier /// characters to the version bytes. The claim launcher can therefore attest /// the full compile-time identity without executing the binary. @@ -1137,15 +1055,17 @@ fn run(cli: Cli, loaded_env: &env_files::Loaded) -> Result<(), String> { // Reads local stores only (list) / writes one rule file // (promote) — works with zero API keys. return match cmd { - MemoryCmd::List { format } => memory_cmd::run_memory_list(*format), - MemoryCmd::Promote { id } => memory_cmd::run_memory_promote(id), - MemoryCmd::Validate => memory_cmd::run_memory_validate(), - MemoryCmd::Forget { id, reason } => memory_cmd::run_memory_forget(id, reason), - MemoryCmd::Edit { id, text } => memory_cmd::run_memory_edit(id, text), - MemoryCmd::Restore { id } => memory_cmd::run_memory_restore(id), - MemoryCmd::Forgotten => memory_cmd::run_memory_forgotten(), - MemoryCmd::Compact(args) => memory_compact::run_memory_compact(args), - MemoryCmd::Index(args) => memory_index::run_memory_index(args), + memory_cmd::MemoryCmd::List { format } => memory_cmd::run_memory_list(*format), + memory_cmd::MemoryCmd::Promote { id } => memory_cmd::run_memory_promote(id), + memory_cmd::MemoryCmd::Validate => memory_cmd::run_memory_validate(), + memory_cmd::MemoryCmd::Forget { id, reason } => { + memory_cmd::run_memory_forget(id, reason) + } + memory_cmd::MemoryCmd::Edit { id, text } => memory_cmd::run_memory_edit(id, text), + memory_cmd::MemoryCmd::Restore { id } => memory_cmd::run_memory_restore(id), + memory_cmd::MemoryCmd::Forgotten => memory_cmd::run_memory_forgotten(), + memory_cmd::MemoryCmd::Compact(args) => memory_compact::run_memory_compact(args), + memory_cmd::MemoryCmd::Index(args) => memory_index::run_memory_index(args), }; } Some(Command::Mcp { cmd }) => { diff --git a/stella-cli/src/memory_cmd.rs b/stella-cli/src/memory_cmd.rs index b3812c67..0280d5ec 100644 --- a/stella-cli/src/memory_cmd.rs +++ b/stella-cli/src/memory_cmd.rs @@ -84,6 +84,22 @@ pub enum MemoryCmd { /// List the tombstones in this workspace — what was forgotten, when, and /// why. Forgotten, + /// Reclaim space in .stella/private/context.db by dropping derived index + /// rows whose owner is already gone: embedding vectors no memory, node or + /// episode points at (every `memory edit` strands one), and domain tags + /// pointing at rows that no longer exist. + /// + /// Memories, episodes, facts and forget tombstones are never touched — + /// point-in-time queries answer identically before and after. + Compact(crate::memory_compact::CompactArgs), + /// Build the approximate-similarity (IVF) index recall can use instead of + /// scoring every stored vector on every turn. + /// + /// Opt-in twice over: this builds it, and `context.retrieval.ann_enabled` + /// in settings.json is what lets a recall use it. An approximate index + /// considers a subset of the corpus, so it can miss a frame the exact scan + /// would have found — which is why neither half is on by default. + Index(crate::memory_index::IndexArgs), } /// Output format for `stella memory list`.