Commit 474e507
committed
Four reliability hardening fixes that improve crash safety, resource
cleanup, and API transparency across the graph pipeline.
Fix 1: wrap incremental_trace_flows DELETEs in a transaction (#258)
-------------------------------------------------------------------
File: code_review_graph/flows.py:499-502
The DELETE loop in incremental_trace_flows deleted flow_memberships and
flows rows one at a time without an explicit transaction. A crash
mid-loop could leave orphaned flow_memberships rows pointing at deleted
flows.
Fix: wrap the DELETE loop in BEGIN IMMEDIATE / COMMIT / ROLLBACK,
matching the pattern already used by store_flows at line 406. Includes
an in_transaction guard to flush any implicit transaction first.
Test: test_incremental_trace_flows_delete_is_atomic — verifies no
orphaned memberships exist after an incremental re-trace.
Fix 2: atomic FTS index rebuild (#259)
--------------------------------------
File: code_review_graph/search.py:39-54
rebuild_fts_index performed DROP, CREATE, and INSERT across three
separate statements with commits between them. A crash after DROP but
before CREATE would leave the DB without an FTS table entirely.
Fix: wrap the entire DROP + CREATE + INSERT sequence in a single
BEGIN IMMEDIATE transaction so the operation is all-or-nothing.
Test: test_fts_rebuild_is_atomic — verifies double-rebuild leaves the
table intact and queryable.
Fix 3: EmbeddingStore context manager support (#260)
----------------------------------------------------
File: code_review_graph/embeddings.py:391+
EmbeddingStore opens a SQLite connection in __init__ but did not
implement __enter__/__exit__. If an exception occurred during usage
before close() was called, the connection leaked.
Fix: add __enter__ and __exit__ methods following the same pattern as
GraphStore (graph.py:154-157).
Test: test_supports_context_manager, test_context_manager_closes_on_exception.
Fix 4: truncation signal for find_dependents (#261)
----------------------------------------------------
File: code_review_graph/incremental.py:434-465
When find_dependents hit _MAX_DEPENDENT_FILES (500), it truncated the
result and logged a warning, but the caller received a plain list with
no indication that it was incomplete. Callers had to guess whether
they got the full dependent set or a truncated one.
Fix: introduce DependentList (a transparent list subclass with a
.truncated boolean attribute). Existing callers that iterate, len(),
or slice continue to work unchanged; only callers that specifically
check .truncated benefit from the signal.
Tests: test_truncated_flag_set_when_capped (600 deps, expects True),
test_truncated_flag_false_when_not_capped (small chain, expects False).
Files changed
-------------
- code_review_graph/flows.py — transaction wrap around DELETE loop
- code_review_graph/search.py — atomic FTS rebuild
- code_review_graph/embeddings.py — __enter__/__exit__ on EmbeddingStore
- code_review_graph/incremental.py — DependentList with .truncated flag
- tests/test_flows.py — orphan membership check
- tests/test_search.py — double-rebuild atomicity test
- tests/test_embeddings.py — context manager tests
- tests/test_incremental.py — truncation flag tests
Test results
------------
Stage 1 (new targeted tests): 6/6 passed.
Stage 2 (all affected test files): 137 passed, 3 pre-existing failures
(find_repo_root flakiness + UTF-8 gitignore — covered by PRs #274/#242).
Stage 3 (full suite): 784 passed, 8 pre-existing Windows failures
(all covered by parallel PRs).
Stage 4 (ruff check on all 8 changed files): clean.
Stage 5 (mypy on all 4 changed source files): clean.
Zero regressions.
1 parent 80d22bf commit 474e507
8 files changed
Lines changed: 206 additions & 25 deletions
File tree
- code_review_graph
- tests
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
418 | 418 | | |
419 | 419 | | |
420 | 420 | | |
| 421 | + | |
| 422 | + | |
| 423 | + | |
| 424 | + | |
| 425 | + | |
| 426 | + | |
421 | 427 | | |
422 | 428 | | |
423 | 429 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
496 | 496 | | |
497 | 497 | | |
498 | 498 | | |
499 | | - | |
500 | | - | |
501 | | - | |
502 | | - | |
| 499 | + | |
| 500 | + | |
| 501 | + | |
| 502 | + | |
| 503 | + | |
| 504 | + | |
| 505 | + | |
| 506 | + | |
| 507 | + | |
| 508 | + | |
| 509 | + | |
| 510 | + | |
| 511 | + | |
| 512 | + | |
| 513 | + | |
| 514 | + | |
503 | 515 | | |
504 | 516 | | |
505 | 517 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
431 | 431 | | |
432 | 432 | | |
433 | 433 | | |
| 434 | + | |
| 435 | + | |
| 436 | + | |
| 437 | + | |
| 438 | + | |
| 439 | + | |
| 440 | + | |
| 441 | + | |
| 442 | + | |
| 443 | + | |
| 444 | + | |
| 445 | + | |
| 446 | + | |
| 447 | + | |
| 448 | + | |
| 449 | + | |
| 450 | + | |
| 451 | + | |
| 452 | + | |
434 | 453 | | |
435 | 454 | | |
436 | 455 | | |
437 | 456 | | |
438 | | - | |
| 457 | + | |
439 | 458 | | |
440 | 459 | | |
441 | 460 | | |
442 | 461 | | |
| 462 | + | |
| 463 | + | |
| 464 | + | |
| 465 | + | |
| 466 | + | |
443 | 467 | | |
444 | 468 | | |
445 | 469 | | |
| |||
460 | 484 | | |
461 | 485 | | |
462 | 486 | | |
463 | | - | |
464 | | - | |
465 | | - | |
| 487 | + | |
| 488 | + | |
| 489 | + | |
| 490 | + | |
| 491 | + | |
466 | 492 | | |
467 | 493 | | |
468 | 494 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
35 | 35 | | |
36 | 36 | | |
37 | 37 | | |
38 | | - | |
39 | | - | |
40 | | - | |
41 | | - | |
42 | | - | |
43 | | - | |
44 | | - | |
45 | | - | |
46 | | - | |
47 | | - | |
48 | | - | |
49 | | - | |
50 | | - | |
51 | | - | |
52 | | - | |
53 | | - | |
54 | | - | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
55 | 62 | | |
56 | 63 | | |
57 | 64 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
345 | 345 | | |
346 | 346 | | |
347 | 347 | | |
| 348 | + | |
| 349 | + | |
| 350 | + | |
| 351 | + | |
| 352 | + | |
| 353 | + | |
| 354 | + | |
| 355 | + | |
| 356 | + | |
| 357 | + | |
| 358 | + | |
| 359 | + | |
| 360 | + | |
| 361 | + | |
| 362 | + | |
| 363 | + | |
| 364 | + | |
| 365 | + | |
| 366 | + | |
| 367 | + | |
| 368 | + | |
| 369 | + | |
| 370 | + | |
| 371 | + | |
| 372 | + | |
| 373 | + | |
| 374 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
558 | 558 | | |
559 | 559 | | |
560 | 560 | | |
| 561 | + | |
| 562 | + | |
| 563 | + | |
| 564 | + | |
| 565 | + | |
| 566 | + | |
| 567 | + | |
| 568 | + | |
| 569 | + | |
| 570 | + | |
| 571 | + | |
| 572 | + | |
| 573 | + | |
| 574 | + | |
| 575 | + | |
| 576 | + | |
| 577 | + | |
| 578 | + | |
| 579 | + | |
| 580 | + | |
| 581 | + | |
| 582 | + | |
| 583 | + | |
| 584 | + | |
| 585 | + | |
| 586 | + | |
| 587 | + | |
| 588 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
592 | 592 | | |
593 | 593 | | |
594 | 594 | | |
| 595 | + | |
| 596 | + | |
| 597 | + | |
| 598 | + | |
| 599 | + | |
| 600 | + | |
| 601 | + | |
| 602 | + | |
| 603 | + | |
| 604 | + | |
| 605 | + | |
| 606 | + | |
| 607 | + | |
| 608 | + | |
| 609 | + | |
| 610 | + | |
| 611 | + | |
| 612 | + | |
| 613 | + | |
| 614 | + | |
| 615 | + | |
| 616 | + | |
| 617 | + | |
| 618 | + | |
| 619 | + | |
| 620 | + | |
| 621 | + | |
| 622 | + | |
| 623 | + | |
| 624 | + | |
| 625 | + | |
| 626 | + | |
| 627 | + | |
| 628 | + | |
| 629 | + | |
| 630 | + | |
| 631 | + | |
| 632 | + | |
| 633 | + | |
| 634 | + | |
| 635 | + | |
| 636 | + | |
| 637 | + | |
| 638 | + | |
| 639 | + | |
| 640 | + | |
| 641 | + | |
| 642 | + | |
| 643 | + | |
| 644 | + | |
| 645 | + | |
| 646 | + | |
| 647 | + | |
| 648 | + | |
| 649 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
248 | 248 | | |
249 | 249 | | |
250 | 250 | | |
| 251 | + | |
| 252 | + | |
| 253 | + | |
| 254 | + | |
| 255 | + | |
| 256 | + | |
| 257 | + | |
| 258 | + | |
| 259 | + | |
| 260 | + | |
| 261 | + | |
| 262 | + | |
| 263 | + | |
| 264 | + | |
| 265 | + | |
| 266 | + | |
| 267 | + | |
| 268 | + | |
| 269 | + | |
| 270 | + | |
0 commit comments