update: entry hash chain と session_head mutex を撤廃

- HashedEntry / EntryHash / compute_hash / build_chain 撤去、JSONL は 1 行 1 LogEntry
- SessionOrigin.at_hash → at_turn_index (TurnEnd 由来) に置換
- Pod 側 SessionHead mutex を ArcSwap<SessionId> + AtomicUsize の SessionState に置換
- ensure_head_or_fork は store の entry count と writer の append tally で判定
- session-store から sha2 / hex 依存、pod から parking_lot 依存を削除
This commit is contained in:
2026-05-20 04:31:37 +09:00
parent 3d091acacd
commit 90e83bf2ae
17 changed files with 339 additions and 653 deletions
+6 -17
View File
@@ -6,7 +6,7 @@
use crate::SessionId;
use crate::event_trace::TraceEntry;
use crate::session_log::{EntryHash, HashedEntry};
use crate::session_log::LogEntry;
use crate::store::{Store, StoreError};
use std::fs;
use std::io::Write;
@@ -65,12 +65,12 @@ impl FsStore {
}
impl Store for FsStore {
fn append(&self, id: SessionId, entry: &HashedEntry) -> Result<(), StoreError> {
fn append(&self, id: SessionId, entry: &LogEntry) -> Result<(), StoreError> {
let line = serde_json::to_string(entry)?;
self.append_line(&self.log_path(id), &line)
}
fn read_all(&self, id: SessionId) -> Result<Vec<HashedEntry>, StoreError> {
fn read_all(&self, id: SessionId) -> Result<Vec<LogEntry>, StoreError> {
let path = self.log_path(id);
if !path.exists() {
return Err(StoreError::NotFound(id));
@@ -98,7 +98,7 @@ impl Store for FsStore {
Ok(sessions)
}
fn create_session(&self, id: SessionId, entries: &[HashedEntry]) -> Result<(), StoreError> {
fn create_session(&self, id: SessionId, entries: &[LogEntry]) -> Result<(), StoreError> {
let path = self.log_path(id);
let mut content = String::new();
for entry in entries {
@@ -113,24 +113,13 @@ impl Store for FsStore {
Ok(self.log_path(id).exists())
}
fn read_head_hash(&self, id: SessionId) -> Result<Option<EntryHash>, StoreError> {
fn read_entry_count(&self, id: SessionId) -> Result<usize, StoreError> {
let path = self.log_path(id);
if !path.exists() {
return Err(StoreError::NotFound(id));
}
let content = fs::read_to_string(&path)?;
let last_line = content.lines().rev().find(|l| !l.trim().is_empty());
match last_line {
Some(line) => {
let entry: HashedEntry =
serde_json::from_str(line).map_err(|e| StoreError::Corrupt {
line: content.lines().count(),
message: e.to_string(),
})?;
Ok(Some(entry.hash))
}
None => Ok(None),
}
Ok(content.lines().filter(|l| !l.trim().is_empty()).count())
}
fn append_trace(&self, id: SessionId, entry: &TraceEntry) -> Result<(), StoreError> {