Skip to content

fix(knowledge): the guard did not apply on the way in, so the store never cleaned - #235

Merged
sshlg merged 1 commit into
mainfrom
fix/the-code-db-map-is-part-of-the-index
Aug 27, 2026
Merged

fix(knowledge): the guard did not apply on the way in, so the store never cleaned#235
sshlg merged 1 commit into
mainfrom
fix/the-code-db-map-is-part-of-the-index

Conversation

@sshlg

@sshlg sshlg commented Aug 27, 2026

Copy link
Copy Markdown
Collaborator

Follow-up to #234, found by measuring production after the deploy rather than assuming the fix landed.

Deploying the guard was not enough

A full re-index ran with the guard live — 9 981 files detected, 8 644 parsed, graph rebuilt to 25 491 symbols — and project_cache.knowledge_json, written at 01:00:16, still held 48 implausible names:

CASCADE  CURRENT_TIMESTAMP  GET  IF  Our  SI  0  200  1328  ases  bs  …

The casing and the bare integers gave it away. The guard rejects every one of those on write, so they were not produced — they were loaded.

ProjectKnowledge.from_json restored table_usage with no filter, and _incremental_update carried the cache forward the same way. A name recorded before the guard existed came back on every run, got re-saved, and outlived any number of clean extractions. Clearing it would have needed a manual purge nobody schedules.

The guard applies on both boundaries now, so one run cleans the store. Verified: loading 13 names — 10 noise, 3 real — yields exactly the three real ones, and a real name survives a round trip with its readers intact.

The map is part of a repo index, not an ingestion automation

auto_sync_after_index defaults ON and leaves the ingestion-automation family.

That family's rule is nothing calls out on a schedule unasked, and the flag never qualified:

code_db_sync_pipeline.py occurrences:
  adapter 0   connector 0   execute_query 0   introspect 0   httpx 0   aiohttp 0

The sync opens no connection to anything. Its inputs are the stored DbIndex and the code knowledge, both already local; its output is the code↔DB map, which is what a repo index produces.

The mis-grouping's consequence appeared the moment it was tested: unset on 2026-08-25 alongside eight genuine ingestion flags, it meant the re-index above rebuilt the graph while the map kept the previous night's updated_at. "The index ran and the map did not" is the wrong default for a product whose value is that map's freshness.

The flag stays, for the reason the old grouping never named. The sync runs an LLM (CodeDbSyncAnalyzer), so it costs tokens per run — turning it off now switches off a cost rather than a phantom outward call. One of the new tests fails if the sync ever grows an outward call, because that would make the classification wrong again.

Production has the flag unset, so the new default applies with no config change and make config-drift stays clean.

The ratchet earned its keep again

Flipping the default turned test_the_ten_that_were_found_are_reported_as_drift red — correctly, since AUTO_SYNC_AFTER_INDEX=true is now agreement rather than divergence. The fixture records why the flag left the set, and asserts the default is True, so if it ever goes back to False this test is the thing that says the flag is drift again.

Suite: 6922 passed, 4 skipped, 1 xfailed.

🤖 Generated with Claude Code

https://claude.ai/code/session_01XtEZboEDbEXLYrLf1owRXB

…ever cleaned

Deploying the guard was not enough, and measuring after the deploy is how that was found.
A full re-index ran in production WITH the guard live — 9 981 files detected, 8 644
parsed, graph rebuilt to 25 491 symbols — and project_cache.knowledge_json, written at
01:00:16, still held 48 implausible names:

  CASCADE  CURRENT_TIMESTAMP  GET  IF  Our  SI  0  200  1328  ases  bs  …

The casing and the bare integers gave it away: the guard rejects all of those on write, so
they were not produced. They were LOADED. `ProjectKnowledge.from_json` restored
table_usage with no filter, and `_incremental_update` carried the cache forward the same
way, so a name recorded before the guard existed came back every run, was re-saved, and
outlived any number of clean extractions. Clearing it would have needed a manual purge
nobody schedules.

The guard applies on both boundaries now. One run cleans the store. Verified: loading 13
names — 10 noise, 3 real — yields exactly the three real ones, and a real name survives a
round trip with its readers intact.

Second change — the map is part of a repo index, not an ingestion automation:

`auto_sync_after_index` defaults ON and leaves the ingestion-automation family. That
family's rule is "nothing calls out on a schedule unasked" and the flag never qualified:
code_db_sync_pipeline.py has zero references to adapter, connector, execute_query,
introspect, httpx or aiohttp. The sync opens no connection to anything — its inputs are
the stored DbIndex and the code knowledge, both local, and its output is the code↔DB map,
which is what a repo index produces.

The mis-grouping's consequence appeared the moment it was tested: unset on 2026-08-25
with eight genuine ingestion flags, it meant the re-index above rebuilt the graph while
the map kept the previous night's updated_at.

The flag stays, for the reason the old grouping never named: the sync runs an LLM
(CodeDbSyncAnalyzer), so it costs tokens per run. One of the new tests fails if the sync
ever grows an outward call, because that would make the classification wrong again.

Production has the flag unset, so the new default applies without a config change and
`make config-drift` stays clean. The config_drift fixture that listed it among the ten
2026-08-23 divergences now records WHY it left rather than being edited silently.

Suite: 6922 passed, 4 skipped, 1 xfailed.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XtEZboEDbEXLYrLf1owRXB
@sshlg
sshlg merged commit a23af82 into main Aug 27, 2026
2 checks passed
@sshlg
sshlg deleted the fix/the-code-db-map-is-part-of-the-index branch August 27, 2026 01:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant