Context
PR #276 code review (finding #4) identified that _get_graph_generation() is implemented 3 times with identical logic but different signatures:
api/app/lib/age_client/query.py:996 — takes cur parameter
api/app/services/confidence_analyzer.py:186 — acquires its own connection
api/app/services/confidence_analyzer.py:379 — _get_graph_generation_on_cursor(), takes cur
All three do the same thing: SAVEPOINT probe for graph_accel.generation, fallback to vocabulary_change_counter from graph_metrics.
Risk
If the generation source changes (e.g., new table, different fallback), all three must be updated in sync. Real drift risk.
Proposed Fix
Extract to a shared helper that takes a cursor, importable by both modules. The two cursor-taking variants collapse into one. The connection-acquiring variant becomes a thin wrapper.
References
Context
PR #276 code review (finding #4) identified that
_get_graph_generation()is implemented 3 times with identical logic but different signatures:api/app/lib/age_client/query.py:996— takescurparameterapi/app/services/confidence_analyzer.py:186— acquires its own connectionapi/app/services/confidence_analyzer.py:379—_get_graph_generation_on_cursor(), takescurAll three do the same thing: SAVEPOINT probe for
graph_accel.generation, fallback tovocabulary_change_counterfromgraph_metrics.Risk
If the generation source changes (e.g., new table, different fallback), all three must be updated in sync. Real drift risk.
Proposed Fix
Extract to a shared helper that takes a cursor, importable by both modules. The two cursor-taking variants collapse into one. The connection-acquiring variant becomes a thin wrapper.
References
.claude/todo-adr-201-graph-accel.md