You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 0899d37
Browse filesBrowse the repository at this point in the historyBrowse files
fix(brain): unwedge suggestion approval and refresh knowledge counts live
Approving code-scan suggestions reported "Approved 0 of 2" and, once
approving worked, the knowledge counts stayed stale until a page reload
while freshly approved items sorted to the bottom of the list.
Approval was permanently wedged
------------------------------
`schema_documentation` carried no unique constraint on
(connection_id, object_type, object_name, parent_object, source) and
`CodeSuggestionApplier.approve` took no row lock, so one bulk approve
submitted twice concurrently wrote 219 duplicate pairs. Every later
approve touching one of those keys threw
`IncorrectResultSizeDataAccessException: Query did not return a unique
result` out of the Optional-returning upsert finder, which bulk-decide
swallowed per item. The duplicate never self-heals, so all 198 pending
SCHEMA_DOC suggestions were unapprovable.
- Those finders now return List; `SchemaDocumentationDeduplicator`
collapses matches, keeps the newest row, repoints any `applied_doc_id`
off the rows it deletes (a loose reference, not an FK, so a dangling
value fails silently) and drops their RAG embeddings. Applied at all
four call sites, including `SchemaDriftListener`.
- `V116__dedupe_schema_documentation.sql` +
`SchemaDocumentationDedupeInitializer` remove the duplicates and add
`ux_schema_doc_target`. There is no Flyway here, so the initializer is
what actually applies it; it is idempotent and skips once the index
exists. On the reporting install: 219 rows and 219 orphaned embeddings
removed, 0 duplicate groups left.
- approve/reject load the suggestion `FOR UPDATE`, so the concurrent
double-submit that created the duplicates blocks instead of racing.
Counts did not refresh
----------------------
An approval also writes `schema_documentation`, served by `brain/notes`,
which backs the Write-notes tab and its coverage counts. The decide hooks
invalidated only codeScan + companyKnowledge, so those counts were stale
until reload. `invalidateAfterDecision` now covers brain and
schemaContext too.
Newest items sorted last
------------------------
- `@PreUpdate` does not fire on insert, so a new note has a null
`updatedAt`; sorting on it alone with nulls last sent every brand-new
note to the bottom. `BrainNoteService` sorts on
COALESCE(updatedAt, createdAt), matching the company-knowledge repo.
- `listSuggestions` sorted every status by confidence, scattering a fresh
approval among hundreds of older ones. PENDING stays confidence-first
(a work queue); decided statuses sort by `decidedAt DESC NULLS LAST`.
Test tooling
------------
Both self-host scripts hardcoded `sudo -u postgres psql`, which does not
exist on the Compose deployment install.sh produces, so the documented
verify command failed before testing anything; they now resolve the path
via `scripts/self-host/vaultdb.py`. The e2e suite also parked every real
CODE_DERIVED row by rewriting source to USER and never restored it,
silently relabelling approved docs on a live install — it now copies rows
to a scratch table and restores them, and only deletes its planted row
while nothing references it. Added cases for duplicate collapse,
applied_doc_id repointing, the unique index, and two genuinely concurrent
approves writing exactly one row: 30/30 pass.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018mG2xj9gWJ8WzfDP2fDePP
0 commit comments