v1.9.1
Fixed
-
Indexing no longer aborts when one file declares the same name twice with different
kinds.let totalin one block andconst totalin another — orclass Xalongside
interface X, which is ordinary TypeScript declaration merging — made the whole index
fail withfqn_identity_collision, discarding every file in the run. Measured on this
repository: the abort came after all 1219 files had been discovered and parsed, roughly
four seconds in, so the visible symptom was a project that simply never became
searchable. The uniqueness check that decides whether a symbol gets the simple
file#nameidentity or a disambiguated one was counting names per(file, name, kind)
while the identity it protects is keyed on(file, name)alone; two declarations
differing only in kind therefore each believed themselves unique and both claimed the
same identity. Same-name/same-kind declarations were already disambiguated correctly and
are unaffected. Symbols that do not share a name keep the identity they had. -
An allow-list with exactly one file extension no longer matches nothing. The three
file scanners built a single combined glob,**/*{.ts,.js,…}. A brace expansion with one
alternative is not an alternation — it is matched literally — so a one-extension allow-list
found zero files and indexing reported success over an empty corpus. Measured: a bounded
index completed in 181 ms over 0 files. This was unreachable while the extension list was
always the 33 built-in defaults, and became reachable with thesecurity.allowedExtensions
fix below; a single-language project is exactly the case where someone sets one extension. -
capturePolicyinconfig.jsonnow actually reaches indexing. The block was parsed,
bounds-checked anddenyUnknownFields-validated at config load, and then never consulted:
applyCapturePolicyhad no caller anywhere in the product, so a configured policy narrowed
nothing. Discovery now applies it after the.gitignoremerge, which is the composition
ignore-patterns.tshas documented since the policy was introduced. With no policy
configured the built-inDEFAULT_POLICYapplies and itsDropset mirrors the default
ignores, so a default install discovers exactly the same files as before.Keepcannot
resurrect a path.gitignoreexcludes — the two layers compose with AND, and the ignore
layer runs first. OnlyDropexcludes;MetadataOnlyfiles are still discovered. -
security.allowedExtensionsinconfig.jsonnow actually narrows what gets indexed.
Setting the key had no effect whatsoever: the assembled config hardcoded the built-in
default list and never read the value, and the user-facing config type did not declare
the field at all — so the value was parsed, then discarded. The indexer, the search index
scanner and the MCP upload collector all read the assembled value, so every consumer saw
the defaults no matter what the file said. Omitting the key still yields the same 33
default extensions, so installs that never set it are unaffected. An empty array is now
rejected at config load rather than honoured: it would match no files, and indexing
would report success over an empty corpus. Entries must be dot-prefixed (.ts, notts). -
search_memorieshonoursincludePersistent. The option has been advertised in the
published MCP tool schema — and forwarded from the tool to the controller — while
nothing ever read it, so a caller passingfalsesilently received persistent memories
anyway. It now excludes L0 (MemoryLevel.PERSISTENT) memories: the level assigned to
orchestrator decisions and criticals, and the one the bootstrap seed writes. The
published schema is unchanged; this makes the existing advertisement true rather than
altering it. Callers passingincludePersistent: falsetoday will see a smaller
result set. The default remainstrue, so callers that omit it are unaffected.