Summary
For an unchanged rebuild fixture, dry-run table-mutation estimates are exactly twice the row counts reported by the real rebuild:
| Metric |
Dry-run |
Persisted after rebuild |
| chunks |
18 |
9 |
| symbols |
110 |
55 |
| symbol references |
322 |
161 |
| reference lines |
198 |
99 |
The preview is summing replacement deletes and inserts, while the execution response reports final persisted cardinality. The output does not distinguish those meanings, so the values appear to be a 2x overestimate.
Reproduced with an isolated fixture using locally built cdidx v1.45.1 at 81861a14c9396cd74190edc91392ab11abfa86f8.
Reproduction
dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll index <project> \
--db <existing.db> --rebuild --dry-run --json
dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll index <project> \
--db <existing.db> --rebuild --yes --json --notify none
Both commands exit 0 and produce the values above.
Expected behavior
Expose unambiguous, mathematically comparable dimensions:
- projected rows deleted;
- projected rows inserted/upserted;
- total row operations, if useful;
- projected final row count or delta where it can be computed.
Do not use the same apparent metric for an operation count in preview and a final/persisted count in execution.
Existing issue relationship
Related history:
No existing issue covers this delete-plus-insert versus persisted-cardinality mismatch.
Root-cause pointers
src/CodeIndex/Cli/IndexCommandRunner.DryRun.cs:420-450 adds existing-row and parsed-row estimates to one accumulator.
AddEstimatedExistingUpdateMutations, AddExistingChildRows, BuildDryRunParsedMutationEstimate, and DryRunMutationEstimateAccumulator in that file own the two sides.
PR scope and implementation guidance
- Define explicit operation and projected-state dimensions in the dry-run result model.
- Prefer additive structured fields; if legacy fields remain, document their exact semantics and deprecation path.
- Keep human and JSON definitions identical.
- Preserve confidence/source/unknown reasons independently for each dimension.
- Ensure arithmetic remains bounded and does not require materializing all rows.
- Do not combine this PR with C# target-expansion or unrelated indexing planner changes.
Acceptance criteria
- The fixture explains 9 deletes plus 9 inserts rather than presenting an unexplained 18-versus-9 mismatch.
- New-database, unchanged rebuild, changed update, delete, purge, skipped, and parse-unavailable fixtures have consistent estimates.
- Unknown values remain explicit rather than zero.
- Existing path/file/truncation budgets remain intact.
- Dry-run remains non-mutating.
Tests, documentation, and changelog
- Add arithmetic fixtures for empty/new DB, unchanged rebuild, changed content, deletes, and parse-unavailable cases.
- Verify JSON and human metric names/definitions.
- Run the complete net8.0 and net9.0 test suites.
- Update dry-run schema/help documentation.
- Add the required bilingual
changelog.d/unreleased/ fragment referencing the prior estimate work.
Summary
For an unchanged rebuild fixture, dry-run table-mutation estimates are exactly twice the row counts reported by the real rebuild:
The preview is summing replacement deletes and inserts, while the execution response reports final persisted cardinality. The output does not distinguish those meanings, so the values appear to be a 2x overestimate.
Reproduced with an isolated fixture using locally built cdidx v1.45.1 at
81861a14c9396cd74190edc91392ab11abfa86f8.Reproduction
Both commands exit 0 and produce the values above.
Expected behavior
Expose unambiguous, mathematically comparable dimensions:
Do not use the same apparent metric for an operation count in preview and a final/persisted count in execution.
Existing issue relationship
Related history:
No existing issue covers this delete-plus-insert versus persisted-cardinality mismatch.
Root-cause pointers
src/CodeIndex/Cli/IndexCommandRunner.DryRun.cs:420-450adds existing-row and parsed-row estimates to one accumulator.AddEstimatedExistingUpdateMutations,AddExistingChildRows,BuildDryRunParsedMutationEstimate, andDryRunMutationEstimateAccumulatorin that file own the two sides.PR scope and implementation guidance
Acceptance criteria
Tests, documentation, and changelog
changelog.d/unreleased/fragment referencing the prior estimate work.