feat: rolegraph session-frequency edge weighting from concept enrichment (f5.3 bullet 3) #37
Notifications
Due Date
No due date set.
Depends on
#42 feat: lesson extractor for F5.3 cross-session learning bullet 1
terraphim/agent-tasks
Reference: terraphim/agent-tasks#37
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Problem Statement
Specification
terraphim-agent-session-search-spec.mdsection F5.3 Cross-Session Learning lists three integration outcomes:Bullets 1 and 2 are tracked: #9 (
/sessions recommend) covers cross-session recommendation, and learning-store correctness is covered by the existingterraphim-agent learn *subcommands. Bullet 3 -- feeding session-derived concept frequency back intoRoleGraphedge weights -- is not tracked in any open agent-tasks issue and is missing from the codebase entirely.A grep across
crates/terraphim_rolegraph/,crates/terraphim_sessions/src/enrichment/, andcrates/terraphim_automata/forsession_frequency,frequency_weight,weight_from_sessions, orupdate_from_sessionsreturns zero hits. The Phase 3 enrichment pipeline (SessionEnricher,ConceptMatch,SessionConcepts) already extracts concept occurrences per session (crates/terraphim_sessions/src/enrichment/) but writes them only to per-session metadata. The aggregated(concept_a, concept_b, co_occurrence_count)signal that the spec asks the role graph to consume is dropped on the floor.Without this, the knowledge graph is permanently snapshot-dated from the original thesaurus build: it never learns which concept pairs the user actually discusses across their imported assistant sessions, and the deterministic search ranking (TerraphimGraph relevance function) cannot give precedence to the user's lived workflow. This is the unique value-add over generic Tantivy / BM25 search and is the only F5 bullet still outstanding.
Past Product Owner runs (notably Run 13 and Run 03) flagged this gap and created phantom issues against
terraphim-ai; this is the real Gitea ticket against the authoritativeagent-tasksrepo.Acceptance Criteria
pub fn weight_from_sessions(&mut self, sessions: &[SessionConcepts]) -> WeightUpdateStats(or similar) toterraphim_rolegraph::RoleGraph.SessionConcepts, increment edge weight on(concept_a, concept_b)pairs that co-occur in the same session by1.0 / log(1 + |concepts_in_session|)(damped frequency to avoid one mega-session dominating).max_per_session(default 10.0) to bound malicious or noisy inputs.(session_id, concept_pair)dedupe set insideWeightUpdateStats).pub struct WeightUpdateStats { sessions_consumed: usize, edges_updated: usize, edges_added: usize, total_weight_delta: f32 }returned for observability.terraphim_sessions::enrichment::SessionEnricher(or addpub fn apply_to_rolegraph(&self, graph: &mut RoleGraph)) so the existing/sessions enrichand import-time enrichment hooks call the new API automatically.terraphim-agent sessions enrich --update-rolegraph(extend the existing enrich subcommand with the boolean flag, defaulttrueso first-class users get the benefit by default; document--no-update-rolegraphfor users who want enrichment-only).terraphim_persistencelayer using the same key namespace as the role graph, so subsequentterraphim-agentruns observe the updated weights.crates/terraphim_rolegraph/tests/session_weights.rs:(async, database)raise that edge weight monotonicallycrates/terraphim_sessions/tests/rolegraph_integration.rsthat imports a synthetic session, applies enrichment, and asserts the role graph's edge weight for the expected concept pair increased.cargo test -p terraphim_rolegraph -p terraphim_sessionspasses.cargo clippy -p terraphim_rolegraph -p terraphim_sessions -- -D warningspasses.Proposed Approach
WeightUpdateStats, persistent dedupe set) toterraphim_rolegraphso the rolegraph crate stays self-contained and other consumers (e.g. server) can call the API without a sessions dependency.weight_from_sessions()onRoleGraphusing the existing edge map; the damped frequency formula keeps the weight scale comparable to the existing thesaurus-derived weights.SessionEnricherso existing tests for enrichment continue to pass; gate behind a feature flag if needed to keepterraphim_rolegraphdecoupled fromterraphim_sessions.Persistablemachinery used byRoleGraphsnapshots so this is durable across REPL sessions.Affected crates:
terraphim_rolegraph(new public API + persistence integration)terraphim_sessions(call site in enrichment pipeline)terraphim_agent(CLI flag onsessions enrich)Affected types/functions to add:
terraphim_rolegraph::RoleGraph::weight_from_sessions()terraphim_rolegraph::WeightUpdateStatsterraphim_sessions::enrichment::SessionEnricher::apply_to_rolegraph()SessionsSubcommand::EnrichDependencies
Soft-pairs with #5 (Tantivy session index) -- this issue uses the existing
SessionConceptsoutput of Phase 3 enrichment, which is already complete. Independent of #9 (/sessions recommend) because that bullet operates over sessions directly, not over the rolegraph.Verification
Scope
Single PR, ~350-450 LOC. The rolegraph public API and tests are the bulk; the sessions integration and CLI flag are small (<60 LOC). No external dependency or schema migration required because the rolegraph already serialises edge weights as
f32.