Description
MessageStore::update_fidelity_tags in crates/zeph-memory/src/store/messages/mod.rs:401 executes one UPDATE messages SET fidelity_tag = ? WHERE id = ? per message in a loop inside a single transaction. For a context window with 100+ messages this is 100+ sequential execute calls.
Code
let mut tx = self.pool.begin().await?;
for &(id, tag) in updates {
zeph_db::query(sql!("UPDATE messages SET fidelity_tag = ? WHERE id = ?"))
.bind(i32::from(tag))
.bind(id)
.execute(&mut *tx)
.await?;
}
tx.commit().await?;
Expected Behavior
A single SQL statement (e.g. UPDATE messages SET fidelity_tag = CASE id WHEN ? THEN ? ... END WHERE id IN (...)) or a temporary table join to batch all updates in one round-trip.
Actual Behavior
N round-trips to the SQLite pool per scoring pass. For a 200-message window this is 200 sequential awaits on the agent's main context-assembly path.
Impact
- Context assembly latency grows linearly with history length.
persist_fidelity_tags is called unconditionally after every score_and_apply, including when most messages have unchanged tags.
Environment
Description
MessageStore::update_fidelity_tagsincrates/zeph-memory/src/store/messages/mod.rs:401executes oneUPDATE messages SET fidelity_tag = ? WHERE id = ?per message in a loop inside a single transaction. For a context window with 100+ messages this is 100+ sequential execute calls.Code
Expected Behavior
A single SQL statement (e.g.
UPDATE messages SET fidelity_tag = CASE id WHEN ? THEN ? ... END WHERE id IN (...)) or a temporary table join to batch all updates in one round-trip.Actual Behavior
N round-trips to the SQLite pool per scoring pass. For a 200-message window this is 200 sequential awaits on the agent's main context-assembly path.
Impact
persist_fidelity_tagsis called unconditionally after everyscore_and_apply, including when most messages have unchanged tags.Environment
crates/zeph-memory/src/store/messages/mod.rs:401crates/zeph-agent-context/src/service.rs:685,:1124