Search session/project/global memory using BM25 over markdown
bodies. Use this to recall content the agent or writer subagent
persisted previously: project memory, session checkpoints, task
narratives (under sessions/<sid>/tasks/), project notes, global
preferences.

Memory layout: <data>/memory/<scope>/<scope_id>/<key>.md
Scopes: global | projects | sessions | cc (opt-in, see below)

QUERY GUIDELINES:
- Queries are OR'd and BM25-ranked: a document matches if it contains
  ANY query word, ordered by relevance (how many / how rare the matched
  words are). Low-relevance common-word-only matches are dropped by a
  score floor.
- Prefer 1–3 distinctive terms (function name, task ID, exact phrase
  from a directive, a rare word from the snippet you want). Long lists
  of generic words ("config params database connection") just add noise
  and bury the real hit — pick the rarest, most specific word.
- "T5.3 closure" works. So does "permission deadlock". Avoid padding
  with generic descriptors.
- Punctuation (`.`, `-`, `/`, `:`) is stripped during tokenization.
  Both query and indexed body see only alphanumeric runs, so `T5.3`
  matches `T5.3`, `T5_3`, or `T5 3`. A literal like `postgres://host:5433`
  is indexed as tokens `postgres`, `host`, `5433` — search one of those,
  not the full URL.

A HIT IS AUTHORITATIVE. If search returns a result, trust it — even
when a different/sibling query you ran returned nothing. Do not conclude
"I never recorded this" because one phrasing missed.

PARTIAL HIT, EXACT LITERAL NEEDED. A hit may give the gist but have
dropped the precise form of a connection string, port, token, full
command line, or path (curation paraphrases). If you need the literal
byte-for-byte and the result only approximates it, query the history
tool — the original message holds it verbatim. Don't reconstruct or
guess the exact value from a paraphrase.

WHEN SEARCH RETURNS 0 (escalate, do not give up):
1. Retry with fewer / rarer terms (see guidelines above).
2. For a literal string the tokenizer splits (URL, port, path) — Grep
   the memory dir directly; FTS can't match the punctuation form.
3. For verbatim recall a summary may have glossed over — use the
   history tool (raw conversation messages).
Widen scope progressively: session → project → global → history.

Actions:
- search: OR-joined BM25 query, optional scope/scope_id/type filters

After search returns paths, use Read on the most relevant ones to
load full content (snippets are truncated). Use Glob on
`<data>/memory/**/*.md` to inspect the tree if you need to find files
by name pattern instead of body.

CC SCOPE:
When memory.cc_index is enabled in config, Claude Code memory at
~/.claude/projects/<slug>/memory/*.md is also indexed under
scope="cc". scope_id is the CC project slug (a path-derived identifier
like "-home-user-projects-app"). Frontmatter metadata.type
(feedback / project / reference / user) populates the type column,
so e.g. type="feedback" filters CC feedback memories. CC memory is
read-only from this tool.

Privacy note: CC's `type: user` and `type: feedback` categories may
hold personal context (the user's role, preferences, prior guidance)
that CC originally wrote for its own future sessions. With cc_index on,
they become recallable from any tulingcode agent — including subagents
that may be exposed to prompt-injected content. If that's not desired,
keep cc_index disabled or filter `type` at search time to exclude
the more sensitive categories.
