Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 19 additions & 7 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,9 @@ jobs:
- uses: actions/checkout@v4

- name: Install Rust
uses: dtolnay/rust-toolchain@stable
uses: dtolnay/rust-toolchain@master
with:
toolchain: "1.97"
components: rustfmt

- name: Check formatting
Expand All @@ -37,8 +38,9 @@ jobs:
sudo apt-get install -y protobuf-compiler libclang-dev

- name: Install Rust
uses: dtolnay/rust-toolchain@stable
uses: dtolnay/rust-toolchain@master
with:
toolchain: "1.97"
components: clippy

- name: Cache cargo registry
Expand Down Expand Up @@ -72,7 +74,9 @@ jobs:
echo "LIBCLANG_PATH=$(brew --prefix llvm)/lib" >> $GITHUB_ENV

- name: Install Rust
uses: dtolnay/rust-toolchain@stable
uses: dtolnay/rust-toolchain@master
with:
toolchain: "1.97"

- name: Cache cargo registry
uses: Swatinem/rust-cache@v2
Expand Down Expand Up @@ -105,7 +109,9 @@ jobs:
echo "LIBCLANG_PATH=$(brew --prefix llvm)/lib" >> $GITHUB_ENV

- name: Install Rust
uses: dtolnay/rust-toolchain@stable
uses: dtolnay/rust-toolchain@master
with:
toolchain: "1.97"

- name: Cache cargo registry
uses: Swatinem/rust-cache@v2
Expand All @@ -127,7 +133,9 @@ jobs:
sudo apt-get install -y protobuf-compiler libclang-dev

- name: Install Rust
uses: dtolnay/rust-toolchain@stable
uses: dtolnay/rust-toolchain@master
with:
toolchain: "1.97"

- name: Cache cargo registry
uses: Swatinem/rust-cache@v2
Expand All @@ -151,7 +159,9 @@ jobs:
sudo apt-get install -y protobuf-compiler libclang-dev

- name: Install Rust
uses: dtolnay/rust-toolchain@stable
uses: dtolnay/rust-toolchain@master
with:
toolchain: "1.97"

- name: Cache cargo registry
uses: Swatinem/rust-cache@v2
Expand Down Expand Up @@ -194,7 +204,9 @@ jobs:
sudo apt-get install -y protobuf-compiler libclang-dev

- name: Install Rust
uses: dtolnay/rust-toolchain@stable
uses: dtolnay/rust-toolchain@master
with:
toolchain: "1.97"

- name: Cache cargo registry
uses: Swatinem/rust-cache@v2
Expand Down
4 changes: 3 additions & 1 deletion .github/workflows/e2e-cli.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,9 @@ jobs:
echo "LIBCLANG_PATH=$(brew --prefix llvm)/lib" >> $GITHUB_ENV

- name: Install Rust
uses: dtolnay/rust-toolchain@stable
uses: dtolnay/rust-toolchain@master
with:
toolchain: "1.97"

- name: Cache cargo registry
uses: Swatinem/rust-cache@v2
Expand Down
3 changes: 2 additions & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,9 @@ jobs:
cargo generate-lockfile

- name: Install Rust
uses: dtolnay/rust-toolchain@stable
uses: dtolnay/rust-toolchain@master
with:
toolchain: "1.97"
targets: ${{ matrix.target }}

- name: Install cross
Expand Down
29 changes: 18 additions & 11 deletions .planning/ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
- ✅ **v2.6 Cognitive Retrieval** — Phases 39-44 (shipped 2026-03-16)
- ✅ **v2.7 Multi-Runtime Portability** — Phases 45-50 (shipped 2026-03-22)
- **v3.0 Competitive Parity & Benchmarks** — Phases 51-53 + Phase 51.5 (in progress; Phase 51.5 merged 2026-04-28)
- **v3.1 Make It True** — Phases 54-58 (in progress; Phase 54 merged 2026-08-30, Phase 55 executing)
- **v3.1 Make It True** — Phases 54-58 (in progress; Phase 54 merged 2026-08-30, Phase 55 merged 2026-08-30, Phase 54.5 executing)

## Phases

Expand Down Expand Up @@ -258,22 +258,29 @@ See: `docs/plans/v3.1-make-it-true-plan.md`

Close the claim/reality gap, then open the shop window. No new capabilities.

### Phase 54: Integration Truth (6/6 plans) — IN EXECUTION 2026-08-30
### Phase 54: Integration Truth (6/6 plans) — COMPLETE 2026-08-30 (PR #32)

- [ ] 54-01: Wire orchestrator into RouteQuery + real LLM reranker
- [ ] 54-02: Fix BM25 outbox no-op (index events)
- [ ] 54-03: Make Hybrid layer hybrid
- [ ] 54-04: One rank-fusion implementation
- [ ] 54-05: Honest daemon flags + attach indexes
- [ ] 54-06: Lock-poisoning recover_lock policy
- [x] 54-01: Wire orchestrator into RouteQuery + real LLM reranker
- [x] 54-02: Fix BM25 outbox no-op (index events)
- [x] 54-03: Make Hybrid layer hybrid
- [x] 54-04: One rank-fusion implementation
- [x] 54-05: Honest daemon flags + attach indexes
- [x] 54-06: Lock-poisoning recover_lock policy

### Phase 55: Performance Truth (0/2)
### Phase 54.5: Truth leaks + CI pin (in execution 2026-08-30)

### Phase 56: Honest Benchmarks (0/3)
- [ ] CI: pin rust-toolchain 1.97; allow `result_large_err` on generated proto
- [ ] Explainability reports what actually ran
- [ ] LLM rerank order survives salience; BM25 events carry text
- [ ] Shared HNSW handle; concurrent fan-out; no per-event grip scan

### Phase 55: Performance Truth — COMPLETE 2026-08-30 (PR #33)

### Phase 56: Honest Benchmarks (PR #34 open)

### Phase 57: Shop Window & Positioning (0/3)

### Phase 58: Launch (side quest)

*Updated: 2026-08-30 — Phase 54 Integration Truth in execution*
*Updated: 2026-08-30 — Phase 54.5 truth-leaks + CI pin in execution*

29 changes: 16 additions & 13 deletions .planning/STATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ gsd_state_version: 1.0
milestone_name: Make It True
status: in_progress
stopped_at: null
last_updated: "2026-08-30T17:30:00.000Z"
last_activity: 2026-08-30 — Phase 55 Performance Truth implemented (medium/warm/30 artifact)
last_updated: "2026-08-30T19:10:00.000Z"
last_activity: 2026-08-30 — Phase 54.5 truth-leaks + CI toolchain pin
progress:
total_phases: 5
completed_phases: 1
total_phases: 6
completed_phases: 2
total_plans: 14
completed_plans: 8
percent: 57
Expand All @@ -20,27 +20,30 @@ progress:
See: .planning/PROJECT.md (updated 2026-03-22)

**Core value:** Agent can answer "what were we talking about last week?" without scanning everything
**Current focus:** v3.1 Phase 55Performance Truth (setup vs query split; honest percentiles)
**Current focus:** v3.1 Phase 54.5close residual Phase 54 honesty leaks and pin CI toolchain

## Current Position

Phase: 55 of 58 (Performance Truth)
Plan: 01-02 implemented on `feature/phase-55-performance-truth` (PR pending)
Status: Phase 54 merged; Phase 55 code + medium/warm/30 artifact ready
Last activity: 2026-08-30 — `single.toc` query p50 = 0.13ms; 64.6s was `toc_build`
Phase: 54.5 of 58 (Truth leaks + CI pin)
Plan: implementing on `feature/phase-54.5-truth-leaks`
Status: Phase 54 merged (#32); Phase 55 merged (#33); Phase 56 PR #34 open (clippy red from toolchain drift)
Last activity: 2026-08-30 — explainability truth, shared HNSW, rust-toolchain.toml 1.97

Progress: [██████░░░░] ~57% (8/14 plans; Phase 55 of 54-58)
Progress: [██████░░░░] ~57% (8/14 plans; Phase 54.5 cleanup)

## Out-of-band Work

### Open PRs

None.
| PR | What | Status |
|---|---|---|
| #34 | Phase 56 Honest Benchmarks | Open; Clippy red (1.98 `result_large_err` on generated tonic stubs) |

### Recently Merged

| PR | What | Merged |
|---|---|---|
| #33 | Phase 55 Performance Truth | 2026-08-30 |
| #32 | Phase 54 Integration Truth | 2026-08-30 |
| #31 | v3.1 Make It True design spec | 2026-08-30 |
| #30 | Phase 53 Benchmark Suite | 2026-08-30 |
Expand All @@ -51,5 +54,5 @@ None.
## Decisions

- v3.1 scope: Make It True — no new capabilities; close claim/reality gap (Phases 54-58)
- Phase 55: split setup vs query in `perf_bench`; p90/p99 withheld below 10/30 samples
- Warm = one setup + N query samples; cold = new store per iteration
- Phase 54.5 before more measurement: explainability must report what ran; shared HNSW handle
- CI pins `rust-toolchain.toml` to 1.97 so floating stable cannot redden main
8 changes: 8 additions & 0 deletions .planning/phases/54.5-truth-leaks/54.5-CONTEXT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Phase 54.5: Truth leaks + CI pin

**Gathered:** 2026-08-30
**Status:** In execution
**Source:** docs/plans/phase-54.5-truth-leaks-plan.md

Close residual claim/reality leaks in Phase 54 wiring and unpin CI from
floating stable Clippy. No new capabilities.
54 changes: 54 additions & 0 deletions .planning/phases/54.5-truth-leaks/54.5-VERIFICATION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
---
phase: 54.5-truth-leaks
verified: 2026-08-30
status: passed
---

# Phase 54.5: Truth leaks + CI toolchain pin

**Phase Goal:** explainability reports what actually ran; LLM rerank survives to the
response; query/prune/dedup share one HNSW handle; Clippy on main is not a
floating-stable hostage.

## Execution evidence

| # | Truth | Status | Evidence |
|---|-------|--------|----------|
| 1 | Generated gRPC stubs do not trip `result_large_err` | VERIFIED | `crates/memory-service/src/lib.rs` `#![allow(clippy::result_large_err)]` on `include_proto!`; clippy `-D warnings` green on 1.97.1 |
| 2 | Toolchain is pinned | VERIFIED | `rust-toolchain.toml` channel `1.97`; CI/e2e/release use `dtolnay/rust-toolchain@master` so the pin is honored |
| 3 | LLM fail-open reports `rerank=heuristic` | VERIFIED | `test_llm_reranker_fail_open_on_completer_error`; `test_llm_reranker_fail_open_on_unparseable_order`; `test_llm_fail_open_reports_heuristic` |
| 4 | `layers_attempted` omits unsupported layers | VERIFIED | `test_layers_attempted_omits_unconfigured_layers`; `test_layers_attempted_omits_unavailable_indexes` |
| 5 | `stop_conditions` / `mode_override` are forwarded | VERIFIED | `query_ranked_with`; `test_sequential_timeout_stops_remaining_layers`; `test_mode_override_sequential_is_honored` |
| 6 | Unknown `--rerank` / `rerank_mode` is rejected | VERIFIED | clap `value_parser`; `test_parse_search_rejects_unknown_rerank`; `test_unknown_rerank_mode_is_rejected` |
| 7 | BM25 event hits carry `text` for LLM rerank | VERIFIED | schema `text` is `TEXT \| STORED`; `test_event_search_returns_text_preview`; `test_llm_rerank_reorders_bm25_hits` asserts non-empty `text_preview` |
| 8 | Salience cannot undo a successful LLM rerank | VERIFIED | `RankingConfig.preserve_order`; `test_preserve_order_skips_resort` |
| 9 | No per-event grip scan on BM25 outbox drain | VERIFIED | `find_grip_for_event` removed from `bm25_updater.rs` |
| 10 | Fan-out is concurrent unless Sequential | VERIFIED | `futures::join_all`; `test_parallel_fan_out_runs_layers_concurrently` (max in-flight ≥ 2) |
| 11 | Query / prune / dedup share one HNSW handle | VERIFIED | `open_query_indexes` runs before prune/dedup; `VectorTeleportHandler::index_handle` passed to both |
| 12 | Dimension comes from the embedder | VERIFIED | `embedder.info().dimension` / `EMBEDDING_DIM`; `HnswConfig::default` uses the constant |

Existing BM25 indexes created before this change do not store `text` and still
need a rebuild for event previews to appear. New indexes (and tests) get the
stored field automatically.

## Crate tests (local, 2026-08-30)

| Crate | Result |
|---|---|
| memory-orchestrator | 34 passed |
| memory-retrieval | 78 passed |
| memory-search | 54 passed |
| memory-service | 125 passed |
| memory-indexing | 48 passed |
| memory-daemon | 93 passed |
| memory-cli | 63 passed |
| memory-vector | 28 passed |
| clippy `-D warnings` (workspace, exclude e2e) | green |
| rustfmt `--check` | green |

## Human verification (blockers)

- [x] `cargo clippy --workspace --all-targets --all-features --exclude e2e-tests -- -D warnings` green
- [x] Orchestrator + retrieval + search + service unit tests green
- [x] `rust-toolchain.toml` present and CI workflows use `@master`
- [ ] Full `cargo test --workspace --all-features` (CI)
3 changes: 1 addition & 2 deletions crates/e2e-tests/src/bin/perf_bench.rs
Original file line number Diff line number Diff line change
Expand Up @@ -693,8 +693,8 @@ async fn build_vector_index(
));
}

let mut vector_id = 1_u64;
for (idx, (text, agent, timestamp_ms)) in texts.iter().enumerate() {
let vector_id = idx as u64 + 1;
let embedder_clone = embedder.clone();
let text_owned = text.clone();
let embedding = tokio::task::spawn_blocking(move || embedder_clone.embed(&text_owned))
Expand All @@ -714,7 +714,6 @@ async fn build_vector_index(
let entry = VectorEntry::new(vector_id, DocType::TocNode, doc_id, *timestamp_ms, text)
.with_agent(agent.clone());
metadata.put(&entry).map_err(|e| e.to_string())?;
vector_id += 1;
}

let index_lock = Arc::new(std::sync::RwLock::new(hnsw_index));
Expand Down
2 changes: 2 additions & 0 deletions crates/e2e-tests/tests/ranking_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ fn test_score_floor_prevents_collapse() {
usage_decay_enabled: true,
decay_factor: 0.15,
score_floor: 0.50,
..Default::default()
};

// Worst case: low salience + extremely high access count
Expand Down Expand Up @@ -157,6 +158,7 @@ fn test_combined_ranking_composition() {
usage_decay_enabled: true,
decay_factor: 0.15,
score_floor: 0.50,
..Default::default()
};

// High-salience but heavily used vs low-salience but fresh
Expand Down
15 changes: 13 additions & 2 deletions crates/memory-cli/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,8 @@ pub struct SearchArgs {
#[arg(long, default_value_t = 10)]
pub top: usize,

/// Rerank mode (e.g., "heuristic", "llm").
#[arg(long)]
/// Rerank mode: "heuristic" or "llm".
#[arg(long, value_parser = ["heuristic", "llm"])]
pub rerank: Option<String>,

/// Output format override.
Expand Down Expand Up @@ -165,6 +165,17 @@ mod tests {
}
}

#[test]
fn test_parse_search_rejects_unknown_rerank() {
let err = Cli::try_parse_from(["memory", "search", "hello", "--rerank", "cross-encoder"])
.unwrap_err();
let msg = err.to_string();
assert!(
msg.contains("invalid value") || msg.contains("possible values"),
"unexpected clap error: {msg}"
);
}

#[test]
fn test_parse_context() {
let cli = Cli::try_parse_from(["memory", "context", "what happened"]).unwrap();
Expand Down
Loading
Loading