diff --git a/HANDOVER.md b/HANDOVER.md index e4084ceb0..061bf2843 100644 --- a/HANDOVER.md +++ b/HANDOVER.md @@ -1,8 +1,38 @@ -# Handover: 2026-04-17 -- FFF Epic #222 Complete + Rust 1.95 Clippy Fixes +# Handover: 2026-06-04 — Issue #2046 SharedLearningStore test fix — PR submitted -**Branch**: main (clean, up to date with origin at `0cae8f77f`) -**Previous Handover**: 2026-04-16 - Sprint Planning + 4 Feature PRs Merged + Issue Housekeeping -**Full handover**: `.docs/handover-2026-04-17.md` +**Agent**: Echo (implementation-swarm-1ab30634) +**Branch**: `task/2046-fix-shared-learning-trust-levels-gh` (origin/main + 2 commits) +**PR**: Gitea #2155 — open, awaiting review + +## Completed + +### Issue #2046 — 5 SharedLearningStore tests fail with --features shared-learning + +Root cause: cli tests skipped the required `L0 → promote_to_l1() → L1` step +before calling `promote_to_l2()`. The `SharedLearning::new()` correctly +initialises to `TrustLevel::L0`; `promote_to_l2()` requires `L1` as documented +in `terraphim_types::shared_learning::test_promote_to_l2_requires_l1`. + +Fix: Added `promote_to_l1()` calls in 5 failing tests. +Single file: `crates/terraphim_agent/tests/shared_learning_cli_tests.rs` + +Verification: 9/9 pass, no regressions in terraphim_types, clippy clean. + +## Critical context for next agent + +### Polyrepo split (E1-E5 complete) +- `gitea/main` ≈ 15 crates (server, firecracker, DSM, tinyclaw, etc.) +- `origin/main` (GitHub) ≈ 58 crates (full monorepo) +- `terraphim_agent`, `terraphim_types`, `terraphim_sessions` are **GitHub only** +- Any worktree based on gitea/main will be MISSING these crates + +### SharedLearning trust level API (strictly sequential) +``` +L0 → promote_to_l1() → L1 → promote_to_l2() → L2 → promote_to_l3() → L3 +``` +`promote_to_l2()` is a no-op from L0. `promote_to_l3()` works unconditionally. + +## Previous handover (2026-04-17) ## Session Summary diff --git a/crates/terraphim_agent/tests/shared_learning_cli_tests.rs b/crates/terraphim_agent/tests/shared_learning_cli_tests.rs index bc26b2637..5a605b4be 100644 --- a/crates/terraphim_agent/tests/shared_learning_cli_tests.rs +++ b/crates/terraphim_agent/tests/shared_learning_cli_tests.rs @@ -38,12 +38,13 @@ async fn shared_list_empty_store() { async fn shared_list_with_trust_level_filter() { let store = create_store().await; - let l1 = SharedLearning::new( + let mut l1 = SharedLearning::new( "L1 learning".to_string(), "content".to_string(), SharedLearningSource::Manual, "test-agent".to_string(), ); + l1.promote_to_l1(); store.insert(l1).await.expect("insert l1"); let mut l2 = SharedLearning::new( @@ -52,6 +53,7 @@ async fn shared_list_with_trust_level_filter() { SharedLearningSource::Manual, "test-agent".to_string(), ); + l2.promote_to_l1(); l2.promote_to_l2(); store.insert(l2).await.expect("insert l2"); @@ -92,6 +94,7 @@ async fn shared_promote_l1_to_l2() { let id = learning.id.clone(); store.insert(learning).await.expect("insert"); + store.promote_to_l1(&id).await.expect("promote to l1"); store.promote_to_l2(&id).await.expect("promote to l2"); let fetched = store.get(&id).await.expect("get after promote"); @@ -124,12 +127,13 @@ async fn shared_stats_counts() { // Insert 2 L1, 1 L2 for i in 0..2 { - let l = SharedLearning::new( + let mut l = SharedLearning::new( format!("L1 item {}", i), "content".to_string(), SharedLearningSource::Manual, "agent".to_string(), ); + l.promote_to_l1(); store.insert(l).await.expect("insert l1"); } @@ -139,6 +143,7 @@ async fn shared_stats_counts() { SharedLearningSource::Manual, "agent".to_string(), ); + l2.promote_to_l1(); l2.promote_to_l2(); store.insert(l2).await.expect("insert l2"); @@ -173,7 +178,7 @@ async fn shared_import_creates_l1_entries() { let error = "remote: error: denied".to_string(); let tags = vec!["git".to_string(), "push".to_string()]; - let shared = SharedLearning::new( + let mut shared = SharedLearning::new( command.clone(), error.clone(), SharedLearningSource::BashHook, @@ -182,6 +187,7 @@ async fn shared_import_creates_l1_entries() { .with_original_command(command) .with_error_context(error) .with_keywords(tags); + shared.promote_to_l1(); store .insert(shared) @@ -236,7 +242,8 @@ async fn shared_store_survives_restart() { let id = learning.id.clone(); store.insert(learning).await.expect("insert"); - // 3. Promote it to L2 + // 3. Promote it to L2 via L1 (required promotion path: L0 → L1 → L2) + store.promote_to_l1(&id).await.expect("promote to l1"); store.promote_to_l2(&id).await.expect("promote to l2"); // 4. Drop the store (simulating process exit)