Fixing docstring elision and project_dir case splits in memstack
Two customer-facing correctness bugs, both discovered by tracing symptoms that turned out to describe themselves wrong.
Docstring elision in the compression proxy
CC's Edit tool kept failing on Python files behind the compression proxy. I traced it to _truncate_python_indexed. When it hit a multi-line docstring, it kept the summary line and advanced past the rest without emitting a record. Continuation lines and the closing quote vanished with no stub and no line label. Function bodies always leave ... (N lines truncated: A-B) behind. That asymmetry was the whole bug. A multi-line docstring read back as a complete one-liner, so anchors were built against text not on disk.
I fixed it on the shared path both callers use. Interior lines now get the same labelled stub as a body. Single-line docstrings stay verbatim because that costs no more than a stub and mirrors the existing policy for one-line function bodies.
Stubbing docstrings costs 1.11% of AST savings, around 313k tokens per month measured against 67 days of proxy stats. Exempting Read results would have cost the whole 47.6% of savings AST contributes and still left the bug reachable via Bash cat or Grep.
Project directory case variants splitting records
I chased bridge_skipped: unknown project and found the message was conflating three distinct faults. Foreman was genuinely unknown. EpsteinScan was ambiguous, not unknown. A lowercase-drive project_dir row written at 17:38 today split one project in two, and the resolver refuses to guess between matches.
I fixed canonicalization and collision collapse in the loader. project_dir is now canonicalized on write to an upper-case drive letter with normalized separators while preserving the display case of the rest. I normalized read filters too, not just writes. Folding the stored rows would otherwise make any caller still passing the old spelling silently see nothing.
I added find_project_dirs_by_name so callers can tell unknown from ambiguous. Length 0, 1, or 2+ distinguishes the three cases.
I shipped the repair as a dry-run-default script, not a one-off UPDATE. Other installs will have the same split.
Bridge auto-registration
The insight bridge now auto-registers an unknown project only when the cwd basename matches the supplied project name. A project cannot be typo'd into existence because the typo would not match the directory the process runs in. No .git requirement and no walk-up.
The bridge deliberately skips whenever MEMSTACK_DB_PATH is set, so end-to-end bridge tests must monkeypatch memory_db.DB_PATH instead of using the env var.
Test problems
The first docstring property tests passed against broken code. _looks_like_python needs at least two top-level def/class/import lines. Single-def samples never entered the transform, and an indented def m does not count. That silently killed two class cases. I added a result != block fired-guard. 13 of 18 then failed pre-fix as they should.
get_lessons missed on the first normalization pass. The full suite caught it via 4 failures in test_search_memory.py. I wrote an AST audit of every function taking project_dir to confirm nothing else was missed.
Backfill deferred
109 bridgeable insights across 7 project names were stranded as of today and need a separate backfill. The bridge only fixes forward. Already-written insights in memstack.db never retry.