Summary
cass index --full still cannot get past the daily_stats repair on current upstream main, despite #326 being closed as fixed by 8110944f.
On a large but ordinary readable corpus, both the released v0.6.22 binary and a fresh optimized build of current main fail after ~33 seconds with:
index failed: rebuilding daily_stats with bounded fallback before index planning for .../agent_search.db | out of memory
This is not host memory exhaustion. The current-main process peaks at about 10.4 GB RSS while the host still has ~702 GiB available. There is no cgroup memory limit, no process RSS/address-space limit, and no kernel/cgroup OOM event. The error is being generated inside CASS/frankensqlite.
This follow-up is intentionally separate from the original #326 report: the transaction-bounded staging change is present in the tested source, but this corpus still reaches the same user-visible failure before index planning.
Environment
released binary: cass 0.6.22
released SHA-256: f6b9ab835affd7fb579ae3c7ecd7b47b13695960c8c24776fc005c514b868782
main commit: 968a5f3c914e975327c998368ab2c5510aa22654
main commit title: fix(indexer): deferred-checkpoint mode uses the bounded bulk-import WAL cadence instead of disabling autocheckpoint
main binary SHA-256: 08309118bd8cd7755b14d1eed6819acef6d9c42d753f0e866d1b4e5851ca1b1c
build: cargo build --release --locked
OS: Linux x86_64, kernel 6.17.0-40-generic
libc: Ubuntu GLIBC 2.42-0ubuntu3.1
CPU: AMD EPYC 9684X, 64 logical CPUs / 64 physical cores
RAM: 885 GiB total, ~702 GiB available during diagnosis
swap: none
DB size: 5,633,396,736 bytes
canonical rows: 5,920 conversations / 967,195 messages
The stale materialization that triggers repair is:
daily_stats rows for agent_slug='all', source_id='all': 18
materialized session_count sum: 640
materialized message_count sum: 126,803
canonical conversation count: 5,920
canonical message count: 967,195
No session content or source paths are needed to reproduce the failure mode.
Reproduction
Build and install current main:
git clone https://github.com/Dicklesworthstone/coding_agent_session_search.git
cd coding_agent_session_search
git checkout 968a5f3c914e975327c998368ab2c5510aa22654
cargo build --release --locked
install -m 0755 target/release/cass ~/.local/bin/cass
Run the full index with a wall-clock guard:
timeout 1800 cass index --full --json --progress-interval-ms 10000
Observed final robot payload on current main:
{
"success": false,
"error": "index failed: rebuilding daily_stats with bounded fallback before index planning for /home/ubuntu/.local/share/coding-agent-search/agent_search.db | out of memory",
"elapsed_ms": 33392,
"code": 9,
"kind": "index",
"retryable": true
}
The released v0.6.22 binary produces the same error in 33,331 ms. Current main reproduced repeatedly in 32.7-33.6 seconds.
Resource evidence: not a machine OOM
A 500 ms /proc/<pid>/status sample during the current-main run showed:
sample RSS KB VmHWM KB CPU
1 5,058,576 5,060,176 99.7%
5 6,358,880 6,360,300 99.7%
9 7,858,580 7,860,108 99.9%
13 9,297,004 9,297,996 99.9%
17 9,969,972 9,970,920 99.8%
21 10,261,548 10,372,108 99.8%
peak 10,373,996 ~100%
At the same time:
MemTotal: 928,370,384 kB
MemAvailable: 736,686,320 kB
CommitLimit: 464,185,192 kB
Committed_AS: 220,188,180 kB
Limits/events:
cgroup v2 memory.max: max
cgroup v2 memory.high: max
cgroup memory.events oom: 0
cgroup memory.events kill: 0
RLIMIT_RSS: unlimited
RLIMIT_AS: unlimited
kernel OOM log entries: none
vm.overcommit_memory: 0
Therefore the machine has hundreds of GiB of real and commit headroom when CASS reports out of memory.
Relevant code path
Current main reaches:
src/indexer/mod.rs
repair_daily_stats_if_drifted
rebuild_daily_stats_from_conversation_packets(...)
-> internal out-of-memory
FrankenStorage::rebuild_daily_stats(...)
-> internal out-of-memory propagated as the final error
src/storage/sqlite.rs
FrankenStorage::rebuild_daily_stats
daily_stats_rebuild_stage temp table
bounded conversation batches
per-conversation bounded message batches
transaction-per-aggregate-batch
The #326 staging/commit changes are visibly present. Yet the fallback still grows to ~10 GiB and fails. The robot error does not identify whether the final failure occurred in:
- the conversation scan,
- the per-conversation message scan,
- the staging-table upsert,
- a transaction commit,
- or the final publish.
It also omits the last successful conversation ID, message index, effective batch sizes, and underlying engine error chain. Those fields would make the next diagnosis much cheaper.
Expected behavior
For this corpus, cass index --full should:
- Rebuild
daily_stats with memory bounded independently of total messages/content.
- Proceed into scan/index planning.
- Finish with
success: true.
- Leave
SUM(session_count) for the all/all rollup equal to canonical conversation count.
- Avoid multi-GB materialization for a 5,920-conversation corpus.
If an engine allocation still fails, the robot error should include a stable phase and cursor/batch telemetry rather than only out of memory.
Suggested implementation checks
These are investigation pointers, not assumptions about the final fix:
- Add phase-tagged context around every query/upsert/commit in
FrankenStorage::rebuild_daily_stats, including:
conversation_scan
message_scan
stage_upsert
stage_commit
publish
- Include
last_conversation_id, conversation_id, cursor_message_idx, and current batch sizes in the propagated error.
- Verify whether frankensqlite's query materialization allocates proportional to the full table even with
LIMIT, especially for:
SELECT m.idx, COALESCE(LENGTH(CAST(m.content AS BLOB)), 0)
FROM messages m
WHERE m.conversation_id = ?1 AND m.idx > ?2
ORDER BY m.conversation_id, m.idx
LIMIT ?3
- Consider using an index-qualified streaming access path or native SQL aggregation by day/agent/source if the current executor cannot keep the query bounded.
- Ensure the initial packet rebuild transaction does not retain all batch writes until the corpus completes; it also reaches the internal OOM before the fallback begins.
Regression test / acceptance criteria
A useful non-private fixture can generate enough messages with large content blobs to force multiple packet and fallback batches while keeping the number of conversations modest.
The test should assert:
- process exits 0;
daily_stats totals match canonical counts;
- both packet and fallback paths are exercised independently;
- progress/cursor telemetry identifies the active phase;
- peak live aggregation state is capped by batch size rather than corpus size;
- rerunning is idempotent and does not rebuild when the archive fingerprint is unchanged.
Relationship to existing issues
I can retest a targeted patch against this 5.6 GB / 967k-message corpus if useful.
Summary
cass index --fullstill cannot get past thedaily_statsrepair on current upstreammain, despite #326 being closed as fixed by8110944f.On a large but ordinary readable corpus, both the released v0.6.22 binary and a fresh optimized build of current
mainfail after ~33 seconds with:This is not host memory exhaustion. The current-main process peaks at about 10.4 GB RSS while the host still has ~702 GiB available. There is no cgroup memory limit, no process RSS/address-space limit, and no kernel/cgroup OOM event. The error is being generated inside CASS/frankensqlite.
This follow-up is intentionally separate from the original #326 report: the transaction-bounded staging change is present in the tested source, but this corpus still reaches the same user-visible failure before index planning.
Environment
The stale materialization that triggers repair is:
No session content or source paths are needed to reproduce the failure mode.
Reproduction
Build and install current main:
Run the full index with a wall-clock guard:
Observed final robot payload on current main:
{ "success": false, "error": "index failed: rebuilding daily_stats with bounded fallback before index planning for /home/ubuntu/.local/share/coding-agent-search/agent_search.db | out of memory", "elapsed_ms": 33392, "code": 9, "kind": "index", "retryable": true }The released v0.6.22 binary produces the same error in 33,331 ms. Current main reproduced repeatedly in 32.7-33.6 seconds.
Resource evidence: not a machine OOM
A 500 ms
/proc/<pid>/statussample during the current-main run showed:At the same time:
Limits/events:
Therefore the machine has hundreds of GiB of real and commit headroom when CASS reports
out of memory.Relevant code path
Current main reaches:
The #326 staging/commit changes are visibly present. Yet the fallback still grows to ~10 GiB and fails. The robot error does not identify whether the final failure occurred in:
It also omits the last successful conversation ID, message index, effective batch sizes, and underlying engine error chain. Those fields would make the next diagnosis much cheaper.
Expected behavior
For this corpus,
cass index --fullshould:daily_statswith memory bounded independently of total messages/content.success: true.SUM(session_count)for theall/allrollup equal to canonical conversation count.If an engine allocation still fails, the robot error should include a stable phase and cursor/batch telemetry rather than only
out of memory.Suggested implementation checks
These are investigation pointers, not assumptions about the final fix:
FrankenStorage::rebuild_daily_stats, including:conversation_scanmessage_scanstage_upsertstage_commitpublishlast_conversation_id,conversation_id,cursor_message_idx, and current batch sizes in the propagated error.LIMIT, especially for:Regression test / acceptance criteria
A useful non-private fixture can generate enough messages with large content blobs to force multiple packet and fallback batches while keeping the number of conversations modest.
The test should assert:
daily_statstotals match canonical counts;Relationship to existing issues
daily_statsfallback and was closed as fixed in8110944f.968a5f3c, which contains8110944f.I can retest a targeted patch against this 5.6 GB / 967k-message corpus if useful.