memtrace-skills 1.2.6 → 1.2.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/skills.js +2 -1
- package/dist/tool-names.d.ts +1 -0
- package/dist/tool-names.js +101 -0
- package/dist/transformers/cursor.js +1 -1
- package/dist/transformers/pi.d.ts +8 -0
- package/dist/transformers/pi.js +36 -6
- package/package.json +1 -1
- package/plugin-assets/index.d.ts +1 -1
- package/plugin-assets/index.js +5 -1
- package/plugins/memtrace-skills/references/mcp-parameters.md +53 -4
- package/plugins/memtrace-skills/skills/memtrace-codebase-exploration/SKILL.md +17 -0
- package/plugins/memtrace-skills/skills/memtrace-first/SKILL.md +206 -230
- package/plugins/memtrace-skills/skills/memtrace-graph/SKILL.md +12 -0
- package/plugins/memtrace-skills/skills/memtrace-index/SKILL.md +19 -2
- package/plugins/memtrace-skills/skills/memtrace-search/SKILL.md +51 -9
- package/skills/commands/memtrace-graph.md +12 -0
- package/skills/commands/memtrace-index.md +19 -2
- package/skills/commands/memtrace-search.md +53 -9
- package/skills/workflows/memtrace-codebase-exploration.md +17 -0
- package/skills/workflows/memtrace-first.md +206 -230
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: memtrace-search
|
|
3
|
-
description: "Find source code with Memtrace hybrid BM25+semantic search: symbols, functions, classes, types, constants, definitions, implementations, logic, or error strings inside code. Use when the user wants to find, search, locate, or look up code or asks where code lives.
|
|
3
|
+
description: "Find source code with Memtrace hybrid BM25+semantic search: symbols, functions, classes, types, constants, definitions, implementations, logic, or error strings inside code. Use when the user wants to find, search, locate, or look up code or asks where code lives. Use Memtrace first; after a diagnosed miss and one targeted retry, allow bounded source verification or fallback. Reindex only for evidence of stale or incomplete coverage."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
## Overview
|
|
@@ -22,11 +22,13 @@ Find code using hybrid BM25 + semantic search (RRF). Primary discovery tool —
|
|
|
22
22
|
| Param | Required | Default | Notes |
|
|
23
23
|
|---|---|---|---|
|
|
24
24
|
| `query` | yes | — | Natural language or symbol text |
|
|
25
|
-
| `repo_id` | no |
|
|
25
|
+
| `repo_id` | no | this store's members | Safe scope inference: omitted, an unambiguous session resolves to its own repository; a multi-repo store fans out across its discovered members |
|
|
26
26
|
| `limit` | no | 20 | Max 100 |
|
|
27
27
|
| `file_path` | no | — | Path/directory substring filter |
|
|
28
28
|
| `as_of` | no | now | ISO-8601 time-travel |
|
|
29
29
|
| `include_diagnostics` | no | false | Set true for `id`, `score` in results |
|
|
30
|
+
| `include_dependency_checks` | no | true | With diagnostics, set false for scores without pre-edit risk checks |
|
|
31
|
+
| `include_context` | no | auto | Query-matched processes, communities and selected callers/callees; auto on for concept queries, off for identifiers |
|
|
30
32
|
|
|
31
33
|
**No `kind` param on `find_code`** — use `find_symbol(kind=...)` to filter by symbol type.
|
|
32
34
|
|
|
@@ -39,7 +41,7 @@ Find code using hybrid BM25 + semantic search (RRF). Primary discovery tool —
|
|
|
39
41
|
| Param | Required | Default | Notes |
|
|
40
42
|
|---|---|---|---|
|
|
41
43
|
| `name` | yes | — | Symbol name to search |
|
|
42
|
-
| `repo_id` | no |
|
|
44
|
+
| `repo_id` | no | inferred | Safe scope inference: one repository is inferred only when that is unambiguous; otherwise the call returns `repo_scope_required` |
|
|
43
45
|
| `fuzzy` | no | false | API field exists; currently exact-match in backend |
|
|
44
46
|
| `edit_distance` | no | 2 | Only when fuzzy enabled |
|
|
45
47
|
| `kind` | no | — | `Function`, `Class`, `Method`, etc. |
|
|
@@ -58,15 +60,33 @@ Full parameter spec for every Memtrace tool: `references/mcp-parameters.md` (bun
|
|
|
58
60
|
|
|
59
61
|
- Exact name → `find_symbol`
|
|
60
62
|
- Behaviour description → `find_code`
|
|
61
|
-
-
|
|
63
|
+
- Every member of this store → omit `repo_id` on `find_code`. `find_symbol` needs one repository and infers it only when that is unambiguous.
|
|
62
64
|
|
|
63
65
|
### 2. Execute search
|
|
64
66
|
|
|
65
67
|
Result shape: see [Output](#output) below.
|
|
66
68
|
|
|
67
|
-
### 3.
|
|
69
|
+
### 3. Inspect query context, then expand if needed
|
|
68
70
|
|
|
69
|
-
|
|
71
|
+
Concept searches include a bounded `context` object. Its process matches and
|
|
72
|
+
community members reference the primary `results` by one-based number. Inspect
|
|
73
|
+
these and the selected callers/callees before making another graph call.
|
|
74
|
+
Use `include_context: true` for identifier context, or `false` for flat results.
|
|
75
|
+
Check `status`, `incomplete_reasons`, `coverage` and `payload_truncated`: omitted
|
|
76
|
+
relationships are not proof of absence. The context contains selected matches,
|
|
77
|
+
not a complete process trace. Worktree overlays report context unavailable until
|
|
78
|
+
their graph is refreshed.
|
|
79
|
+
|
|
80
|
+
For a code change, inspect the relevant caller/callee contracts before editing.
|
|
81
|
+
`context.next_calls` supplies valid tool names and arguments for the selected
|
|
82
|
+
symbol and flow; use these directly when they address the investigation.
|
|
83
|
+
They preserve repository, branch and file disambiguation. Process navigation
|
|
84
|
+
uses the returned process UUID. Symbol navigation uses name plus file path.
|
|
85
|
+
Expand only the evidence needed; an empty sampled process list does not mean
|
|
86
|
+
the symbol has no callers or callees.
|
|
87
|
+
|
|
88
|
+
For symbol navigation, save **`name`**, **`scope_path`**, and **`file_path`**.
|
|
89
|
+
For process navigation, retain its **process `id`**:
|
|
70
90
|
|
|
71
91
|
```json
|
|
72
92
|
{ "repo_id": "memdb", "symbol": "validateToken" }
|
|
@@ -74,12 +94,12 @@ Save **`name`**, **`scope_path`**, and **`file_path`** — **not** internal IDs:
|
|
|
74
94
|
{ "repo_id": "memdb", "target": "validateToken", "query_type": "find_callers" }
|
|
75
95
|
```
|
|
76
96
|
|
|
77
|
-
Read source
|
|
97
|
+
Read source when verifying behavior, editing or quoting — bounded `Read(offset, limit)` at returned lines.
|
|
78
98
|
|
|
79
99
|
### Multi-word queries
|
|
80
100
|
|
|
81
101
|
1. Try verbatim `find_code` query.
|
|
82
|
-
2. If weak,
|
|
102
|
+
2. If weak, make one targeted reformulation with an identifier or path hint.
|
|
83
103
|
3. Dedupe top hits by `file_path:start_line`.
|
|
84
104
|
|
|
85
105
|
## Output
|
|
@@ -98,6 +118,23 @@ One `find_code` / `find_symbol` result entry:
|
|
|
98
118
|
|
|
99
119
|
`score` (and `id`) appear only with `include_diagnostics: true`.
|
|
100
120
|
|
|
121
|
+
## A `repo_id` this store does not hold
|
|
122
|
+
|
|
123
|
+
`find_code` and `find_symbol` check membership before they search. If the
|
|
124
|
+
`repo_id` you passed is not a member of this session's store, the call is
|
|
125
|
+
handed to the live runtime whose store declares it, and the answer comes back
|
|
126
|
+
marked `_meta.answered_by: "store_owner_daemon"` with `_meta.owner_pid`,
|
|
127
|
+
`_meta.owner_http` and `_meta.store`. Use that answer and say which store
|
|
128
|
+
produced it.
|
|
129
|
+
|
|
130
|
+
If no live runtime holds the repository, or its owner cannot answer, you get
|
|
131
|
+
a refusal instead: `repo_in_store: false`, `error_code: "repo_not_in_store"`,
|
|
132
|
+
`count: 0`, and a `diagnostic` naming this store, its `members` and — when it
|
|
133
|
+
is known — `repo_lives_in`. Nothing was searched. Do not read that as an
|
|
134
|
+
empty index, do not switch to grep, and do not index the repository into this
|
|
135
|
+
store. Route the question to the session attached to the store the diagnostic
|
|
136
|
+
names.
|
|
137
|
+
|
|
101
138
|
## Common Mistakes
|
|
102
139
|
|
|
103
140
|
| Mistake | Reality |
|
|
@@ -105,4 +142,9 @@ One `find_code` / `find_symbol` result entry:
|
|
|
105
142
|
| `find_code(kind=...)` | **`kind` only on `find_symbol`** |
|
|
106
143
|
| Passing symbol `id` to graph tools | Use **`name`** as `symbol` / `target` |
|
|
107
144
|
| Assuming `fuzzy: true` always works | Backend is exact-match today — try spelling variants |
|
|
108
|
-
| Skipping `list_indexed_repositories` | Verify repo is indexed first |
|
|
145
|
+
| Skipping `list_indexed_repositories` | Verify repo is indexed first — it lists this session's store only |
|
|
146
|
+
| Reading `repo_not_in_store` as an empty index | Nothing was searched; the repository lives in the store `diagnostic.repo_lives_in` names |
|
|
147
|
+
|
|
148
|
+
## Retrieval limits and fallback
|
|
149
|
+
|
|
150
|
+
A valid empty or irrelevant result is not a guarantee that the code is absent. Check scope, branch and indexing/embedding readiness; retry once with a targeted query. Then permit bounded source search and verification. Record the original miss and do not count fallback recovery as Memtrace retrieval success. Reindex only for demonstrated stale or incomplete coverage. Embeddings cannot guarantee literal-string or short-symbol recall. A `repo_not_in_store` refusal is not such a miss: nothing was searched, so route it to the store `diagnostic.repo_lives_in` names rather than falling back to source search or reindexing here.
|
|
@@ -85,6 +85,18 @@ Params are **`source`** and **`target`** (symbol names) — not `from`/`to`.
|
|
|
85
85
|
|
|
86
86
|
`find_dependency_path` returns the ordered symbol chain from `source` to `target`; `list_communities` returns module partitions with their member symbols.
|
|
87
87
|
|
|
88
|
+
## A `busy` answer is a wait, not an absence
|
|
89
|
+
|
|
90
|
+
Heavy graph work runs one repository-sized fold at a time, because holding
|
|
91
|
+
two in memory is what the bound protects against. When the lane is already
|
|
92
|
+
held, a caller is not queued indefinitely: after a bounded wait it gets a
|
|
93
|
+
successful answer carrying `"busy": true`, `"lane": "graph_materialization"`,
|
|
94
|
+
`"retryable": true`, and a `holder` block naming the operation that holds the
|
|
95
|
+
lane and how long it has held it. Report it as a wait, retry once the holder
|
|
96
|
+
is likely done, or narrow the call (one `repo_id`, a smaller `limit`, a
|
|
97
|
+
shorter window) so it does not need the lane. Do not read it as an empty
|
|
98
|
+
graph and do not fall back to file search.
|
|
99
|
+
|
|
88
100
|
## Common Mistakes
|
|
89
101
|
|
|
90
102
|
| Mistake | Reality |
|
|
@@ -43,6 +43,13 @@ root (for example `ui/`, `memtrace-ui/`, `web/`, `frontend/`, or `src/`), treat
|
|
|
43
43
|
that as a stale/partial index. Do not use grep as a workaround. Run incremental
|
|
44
44
|
indexing on the repo root, then retry the Memtrace query.
|
|
45
45
|
|
|
46
|
+
If a search instead came back with `error_code: "repo_not_in_store"`, stop.
|
|
47
|
+
That repository is not missing from the index; it is indexed in a different
|
|
48
|
+
store, named in `diagnostic.repo_lives_in`. `list_indexed_repositories` lists
|
|
49
|
+
this session's store only, so its absence there proves nothing. Indexing it
|
|
50
|
+
here would build a second copy in the wrong store. Report the store that holds
|
|
51
|
+
it and route the question to the session or daemon attached to that store.
|
|
52
|
+
|
|
46
53
|
### 2. Index the directory
|
|
47
54
|
|
|
48
55
|
Use the `index_directory` MCP tool:
|
|
@@ -54,10 +61,20 @@ Use the `index_directory` MCP tool:
|
|
|
54
61
|
If the selected path is just a folder containing multiple independent git repos,
|
|
55
62
|
do not index that parent folder unless the user explicitly wants a shared
|
|
56
63
|
workspace. For separate repos, index each repo root separately. For intentional
|
|
57
|
-
sharing,
|
|
58
|
-
`memtrace start --
|
|
64
|
+
sharing, the durable form is a portable manifest started with
|
|
65
|
+
`memtrace start --workspace-file <manifest>`; the legacy Folder Group flow is
|
|
66
|
+
`memtrace start --bless-workspace` from the parent, verified with
|
|
59
67
|
`memtrace workspace status <path>`.
|
|
60
68
|
|
|
69
|
+
A store whose membership is already owned by a manifest or a Named Workspace
|
|
70
|
+
cannot be widened from an MCP session, nor by a plain `memtrace start` from a
|
|
71
|
+
parent folder. Adding a repository means restarting that store's daemon with
|
|
72
|
+
the definition that owns it — `memtrace start --workspace-file <manifest>` or
|
|
73
|
+
`memtrace start --workspace <name>`, editing the manifest first when it is a
|
|
74
|
+
manifest. If a start is refused with "a folder-walked start cannot widen it",
|
|
75
|
+
run the command the refusal names. No MCP session can widen an existing store
|
|
76
|
+
under any flag, whatever declared it.
|
|
77
|
+
|
|
61
78
|
**Success criteria:** You receive a `job_id` immediately.
|
|
62
79
|
|
|
63
80
|
### 3. Poll for completion
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: memtrace-search
|
|
3
|
-
description: "Find source code with Memtrace hybrid BM25+semantic search: symbols, functions, classes, types, constants, definitions, implementations, logic, or error strings inside code. Use when the user wants to find, search, locate, or look up code or asks where code lives.
|
|
3
|
+
description: "Find source code with Memtrace hybrid BM25+semantic search: symbols, functions, classes, types, constants, definitions, implementations, logic, or error strings inside code. Use when the user wants to find, search, locate, or look up code or asks where code lives. Use Memtrace first; after a diagnosed miss and one targeted retry, allow bounded source verification or fallback. Reindex only for evidence of stale or incomplete coverage."
|
|
4
4
|
allowed-tools:
|
|
5
5
|
- mcp__memtrace__find_code
|
|
6
6
|
- mcp__memtrace__find_symbol
|
|
7
|
+
- mcp__memtrace__get_symbol_context
|
|
8
|
+
- mcp__memtrace__get_process_flow
|
|
7
9
|
- mcp__memtrace__get_source_window
|
|
8
10
|
- mcp__memtrace__list_indexed_repositories
|
|
9
11
|
- Read
|
|
@@ -32,11 +34,13 @@ Find code using hybrid BM25 + semantic search (RRF). Primary discovery tool —
|
|
|
32
34
|
| Param | Required | Default | Notes |
|
|
33
35
|
|---|---|---|---|
|
|
34
36
|
| `query` | yes | — | Natural language or symbol text |
|
|
35
|
-
| `repo_id` | no |
|
|
37
|
+
| `repo_id` | no | this store's members | Safe scope inference: omitted, an unambiguous session resolves to its own repository; a multi-repo store fans out across its discovered members |
|
|
36
38
|
| `limit` | no | 20 | Max 100 |
|
|
37
39
|
| `file_path` | no | — | Path/directory substring filter |
|
|
38
40
|
| `as_of` | no | now | ISO-8601 time-travel |
|
|
39
41
|
| `include_diagnostics` | no | false | Set true for `id`, `score` in results |
|
|
42
|
+
| `include_dependency_checks` | no | true | With diagnostics, set false for scores without pre-edit risk checks |
|
|
43
|
+
| `include_context` | no | auto | Query-matched processes, communities and selected callers/callees; auto on for concept queries, off for identifiers |
|
|
40
44
|
|
|
41
45
|
**No `kind` param on `find_code`** — use `find_symbol(kind=...)` to filter by symbol type.
|
|
42
46
|
|
|
@@ -49,7 +53,7 @@ Find code using hybrid BM25 + semantic search (RRF). Primary discovery tool —
|
|
|
49
53
|
| Param | Required | Default | Notes |
|
|
50
54
|
|---|---|---|---|
|
|
51
55
|
| `name` | yes | — | Symbol name to search |
|
|
52
|
-
| `repo_id` | no |
|
|
56
|
+
| `repo_id` | no | inferred | Safe scope inference: one repository is inferred only when that is unambiguous; otherwise the call returns `repo_scope_required` |
|
|
53
57
|
| `fuzzy` | no | false | API field exists; currently exact-match in backend |
|
|
54
58
|
| `edit_distance` | no | 2 | Only when fuzzy enabled |
|
|
55
59
|
| `kind` | no | — | `Function`, `Class`, `Method`, etc. |
|
|
@@ -68,15 +72,33 @@ Full parameter spec for every Memtrace tool: `references/mcp-parameters.md` (bun
|
|
|
68
72
|
|
|
69
73
|
- Exact name → `find_symbol`
|
|
70
74
|
- Behaviour description → `find_code`
|
|
71
|
-
-
|
|
75
|
+
- Every member of this store → omit `repo_id` on `find_code`. `find_symbol` needs one repository and infers it only when that is unambiguous.
|
|
72
76
|
|
|
73
77
|
### 2. Execute search
|
|
74
78
|
|
|
75
79
|
Result shape: see [Output](#output) below.
|
|
76
80
|
|
|
77
|
-
### 3.
|
|
81
|
+
### 3. Inspect query context, then expand if needed
|
|
78
82
|
|
|
79
|
-
|
|
83
|
+
Concept searches include a bounded `context` object. Its process matches and
|
|
84
|
+
community members reference the primary `results` by one-based number. Inspect
|
|
85
|
+
these and the selected callers/callees before making another graph call.
|
|
86
|
+
Use `include_context: true` for identifier context, or `false` for flat results.
|
|
87
|
+
Check `status`, `incomplete_reasons`, `coverage` and `payload_truncated`: omitted
|
|
88
|
+
relationships are not proof of absence. The context contains selected matches,
|
|
89
|
+
not a complete process trace. Worktree overlays report context unavailable until
|
|
90
|
+
their graph is refreshed.
|
|
91
|
+
|
|
92
|
+
For a code change, inspect the relevant caller/callee contracts before editing.
|
|
93
|
+
`context.next_calls` supplies valid tool names and arguments for the selected
|
|
94
|
+
symbol and flow; use these directly when they address the investigation.
|
|
95
|
+
They preserve repository, branch and file disambiguation. Process navigation
|
|
96
|
+
uses the returned process UUID. Symbol navigation uses name plus file path.
|
|
97
|
+
Expand only the evidence needed; an empty sampled process list does not mean
|
|
98
|
+
the symbol has no callers or callees.
|
|
99
|
+
|
|
100
|
+
For symbol navigation, save **`name`**, **`scope_path`**, and **`file_path`**.
|
|
101
|
+
For process navigation, retain its **process `id`**:
|
|
80
102
|
|
|
81
103
|
```json
|
|
82
104
|
{ "repo_id": "memdb", "symbol": "validateToken" }
|
|
@@ -84,12 +106,12 @@ Save **`name`**, **`scope_path`**, and **`file_path`** — **not** internal IDs:
|
|
|
84
106
|
{ "repo_id": "memdb", "target": "validateToken", "query_type": "find_callers" }
|
|
85
107
|
```
|
|
86
108
|
|
|
87
|
-
Read source
|
|
109
|
+
Read source when verifying behavior, editing or quoting — bounded `Read(offset, limit)` at returned lines.
|
|
88
110
|
|
|
89
111
|
### Multi-word queries
|
|
90
112
|
|
|
91
113
|
1. Try verbatim `find_code` query.
|
|
92
|
-
2. If weak,
|
|
114
|
+
2. If weak, make one targeted reformulation with an identifier or path hint.
|
|
93
115
|
3. Dedupe top hits by `file_path:start_line`.
|
|
94
116
|
|
|
95
117
|
## Output
|
|
@@ -108,6 +130,23 @@ One `find_code` / `find_symbol` result entry:
|
|
|
108
130
|
|
|
109
131
|
`score` (and `id`) appear only with `include_diagnostics: true`.
|
|
110
132
|
|
|
133
|
+
## A `repo_id` this store does not hold
|
|
134
|
+
|
|
135
|
+
`find_code` and `find_symbol` check membership before they search. If the
|
|
136
|
+
`repo_id` you passed is not a member of this session's store, the call is
|
|
137
|
+
handed to the live runtime whose store declares it, and the answer comes back
|
|
138
|
+
marked `_meta.answered_by: "store_owner_daemon"` with `_meta.owner_pid`,
|
|
139
|
+
`_meta.owner_http` and `_meta.store`. Use that answer and say which store
|
|
140
|
+
produced it.
|
|
141
|
+
|
|
142
|
+
If no live runtime holds the repository, or its owner cannot answer, you get
|
|
143
|
+
a refusal instead: `repo_in_store: false`, `error_code: "repo_not_in_store"`,
|
|
144
|
+
`count: 0`, and a `diagnostic` naming this store, its `members` and — when it
|
|
145
|
+
is known — `repo_lives_in`. Nothing was searched. Do not read that as an
|
|
146
|
+
empty index, do not switch to grep, and do not index the repository into this
|
|
147
|
+
store. Route the question to the session attached to the store the diagnostic
|
|
148
|
+
names.
|
|
149
|
+
|
|
111
150
|
## Common Mistakes
|
|
112
151
|
|
|
113
152
|
| Mistake | Reality |
|
|
@@ -115,4 +154,9 @@ One `find_code` / `find_symbol` result entry:
|
|
|
115
154
|
| `find_code(kind=...)` | **`kind` only on `find_symbol`** |
|
|
116
155
|
| Passing symbol `id` to graph tools | Use **`name`** as `symbol` / `target` |
|
|
117
156
|
| Assuming `fuzzy: true` always works | Backend is exact-match today — try spelling variants |
|
|
118
|
-
| Skipping `list_indexed_repositories` | Verify repo is indexed first |
|
|
157
|
+
| Skipping `list_indexed_repositories` | Verify repo is indexed first — it lists this session's store only |
|
|
158
|
+
| Reading `repo_not_in_store` as an empty index | Nothing was searched; the repository lives in the store `diagnostic.repo_lives_in` names |
|
|
159
|
+
|
|
160
|
+
## Retrieval limits and fallback
|
|
161
|
+
|
|
162
|
+
A valid empty or irrelevant result is not a guarantee that the code is absent. Check scope, branch and indexing/embedding readiness; retry once with a targeted query. Then permit bounded source search and verification. Record the original miss and do not count fallback recovery as Memtrace retrieval success. Reindex only for demonstrated stale or incomplete coverage. Embeddings cannot guarantee literal-string or short-symbol recall. A `repo_not_in_store` refusal is not such a miss: nothing was searched, so route it to the store `diagnostic.repo_lives_in` names rather than falling back to source search or reindexing here.
|
|
@@ -33,6 +33,11 @@ Call `list_indexed_repositories` first. If the repo is already indexed, skip to
|
|
|
33
33
|
|
|
34
34
|
Otherwise, call `index_directory` with the project path, then poll `check_job_status` until completion.
|
|
35
35
|
|
|
36
|
+
`list_indexed_repositories` covers this session's store only. If a later call
|
|
37
|
+
answers `error_code: "repo_not_in_store"`, the repository is indexed in the
|
|
38
|
+
store named in `diagnostic.repo_lives_in` — route the question there instead
|
|
39
|
+
of indexing a second copy here.
|
|
40
|
+
|
|
36
41
|
**Success criteria:** Repo appears in `list_indexed_repositories` with non-zero node/edge counts.
|
|
37
42
|
|
|
38
43
|
### 2. Get the lay of the land
|
|
@@ -134,6 +139,18 @@ The deliverable is the 7-part overview above. Skeleton (one headline per part):
|
|
|
134
139
|
6. Recent Activity — 31 episodes in 30d; hottest file per `top_changed_files`
|
|
135
140
|
7. Technical Debt — top-10 complex functions, highest complexity first
|
|
136
141
|
|
|
142
|
+
## A `busy` answer is a wait, not an absence
|
|
143
|
+
|
|
144
|
+
Heavy graph work runs one repository-sized fold at a time, because holding
|
|
145
|
+
two in memory is what the bound protects against. When the lane is already
|
|
146
|
+
held, a caller is not queued indefinitely: after a bounded wait it gets a
|
|
147
|
+
successful answer carrying `"busy": true`, `"lane": "graph_materialization"`,
|
|
148
|
+
`"retryable": true`, and a `holder` block naming the operation that holds the
|
|
149
|
+
lane and how long it has held it. Report it as a wait, retry once the holder
|
|
150
|
+
is likely done, or narrow the call (one `repo_id`, a smaller `limit`, a
|
|
151
|
+
shorter window) so it does not need the lane. Do not read it as an empty
|
|
152
|
+
graph and do not fall back to file search.
|
|
153
|
+
|
|
137
154
|
## Common Mistakes
|
|
138
155
|
|
|
139
156
|
| Mistake | Reality |
|