Summary
On a copied database with no physical -wal or -shm files before invocation, vacuum --json reports nonzero WAL and SHM sizes in its before telemetry.
Those sidecars are created by the command itself before it captures the baseline.
Reproduced with an isolated database copy using locally built cdidx v1.45.1 at 81861a14c9396cd74190edc91392ab11abfa86f8.
Reproduction
cp <db> <vacuum.db>
test ! -e <vacuum.db>-wal
test ! -e <vacuum.db>-shm
dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll vacuum \
--db <vacuum.db> --json
Observed:
page_count: 159 -> 159;
freelist_count: 0 -> 0;
pages_reclaimed: 0;
bytes_reclaimed: 0;
wal_file_bytes_before: 4152;
shm_file_bytes_before: 32768;
- physical file set appears to shrink by about 36.9 KiB despite reclaiming no pages.
Expected behavior
before must describe the filesystem state at command entry, or the contract must expose separate command-entry and post-open/pre-vacuum observation points clearly enough that they cannot be confused.
Existing issue relationship
Related but not duplicate:
This issue concerns the measurement boundary created by the vacuum command itself.
Root-cause pointers
src/CodeIndex/Cli/QueryCommandRunner.Maintenance.cs:89-104 opens the repair connection before the baseline is finalized.
src/CodeIndex/Database/DbContext.ConnectionLifecycle.cs:478-559 captures before fields from inside that connection lifecycle.
- Close-time correction around lines 712-775 adjusts the after side only.
PR scope and implementation guidance
- Capture main/WAL/SHM existence and sizes before any SQLite connection, pragma, checkpoint, or sidecar permission operation.
- Keep logical SQLite page metrics at their clearly named post-open observation point.
- If both entry and pre-vacuum states are needed, expose them as distinct structured snapshots rather than overloading
before.
- Preserve URI/read-only handling and owner-only sidecar permission hardening.
- Make races explicit with bounded diagnostics; do not silently mix values from different times.
- Define absent sidecars consistently with existence flags or documented zero/null semantics.
Acceptance criteria
- A database with no entry sidecars reports them as absent or zero at command entry.
- Pre-existing nonempty sidecars retain their actual entry sizes.
- Before/after physical-byte arithmetic is internally consistent.
- Zero reclaimed pages cannot look like vacuum reclaimed command-created sidecars.
- WAL, non-WAL, busy checkpoint, failure, Windows, and POSIX paths remain safe.
Tests, documentation, and changelog
- Add filesystem-level tests for absent, empty, and nonempty entry sidecars.
- Cover WAL/non-WAL, busy/failure, dry-run/real modes, and permission hardening.
- Run the complete net8.0 and net9.0 test suites.
- Update maintenance telemetry documentation if field meanings or schema change.
- Add the required bilingual
changelog.d/unreleased/ fragment.
Summary
On a copied database with no physical
-walor-shmfiles before invocation,vacuum --jsonreports nonzero WAL and SHM sizes in itsbeforetelemetry.Those sidecars are created by the command itself before it captures the baseline.
Reproduced with an isolated database copy using locally built cdidx v1.45.1 at
81861a14c9396cd74190edc91392ab11abfa86f8.Reproduction
Observed:
page_count: 159 -> 159;freelist_count: 0 -> 0;pages_reclaimed: 0;bytes_reclaimed: 0;wal_file_bytes_before: 4152;shm_file_bytes_before: 32768;Expected behavior
beforemust describe the filesystem state at command entry, or the contract must expose separate command-entry and post-open/pre-vacuum observation points clearly enough that they cannot be confused.Existing issue relationship
Related but not duplicate:
This issue concerns the measurement boundary created by the vacuum command itself.
Root-cause pointers
src/CodeIndex/Cli/QueryCommandRunner.Maintenance.cs:89-104opens the repair connection before the baseline is finalized.src/CodeIndex/Database/DbContext.ConnectionLifecycle.cs:478-559captures before fields from inside that connection lifecycle.PR scope and implementation guidance
before.Acceptance criteria
Tests, documentation, and changelog
changelog.d/unreleased/fragment.