teamai-cli 0.20.0-beta.6 → 0.20.0-beta.7

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/README.md CHANGED
@@ -175,8 +175,17 @@ Author: member-a | Score: 18.5 | Tags: troubleshooting, networking
175
175
 
176
176
  [2/2] Deployment configuration best practices [project]
177
177
  Author: member-b | Score: 12.0 | Tags: deploy, config
178
+ Matched: conflict | Missing: port
178
179
  ```
179
180
 
181
+ A `Matched: … | Missing: …` line appears whenever a hit does not cover every
182
+ query term (omitted when all terms matched). Recall returns its top matches by
183
+ score without filtering on coverage: a hit missing all of your distinctive
184
+ terms is topically adjacent, not an answer. Judging that is the caller's job —
185
+ the score alone cannot express it. Entries matching on title, date, author and
186
+ content are collapsed, so the same learning shared twice does not occupy two
187
+ slots.
188
+
180
189
  **Coverage spans two parts:**
181
190
 
182
191
  - **Shared search index** (`search-index.json`): four categories — learnings (session experience), docs (team docs), rules (coding rules), and skills (each `SKILL.md`) — sourced from the corresponding team-repo directories, (re)built on `teamai pull` / `teamai contribute`.
package/README.zh-CN.md CHANGED
@@ -175,8 +175,14 @@ Author: member-a | Score: 18.5 | Tags: troubleshooting, networking
175
175
 
176
176
  [2/2] Deployment configuration best practices [project]
177
177
  Author: member-b | Score: 12.0 | Tags: deploy, config
178
+ Matched: conflict | Missing: port
178
179
  ```
179
180
 
181
+ 当某条结果未覆盖全部查询词时,会输出 `Matched: … | Missing: …` 行(全部命中时省略)。
182
+ recall 按分数返回 top 结果,**不会**按覆盖度过滤:若你的关键区分词全在 `Missing:` 里,
183
+ 说明这条只是主题相邻,并非答案。这个判断由调用方来做 —— 分数本身无法表达它。
184
+ 标题、日期、作者与内容均相同的条目会被合并,因此同一条 learning 被分享两次不会占用两个名额。
185
+
180
186
  **检索内容覆盖两部分**:
181
187
 
182
188
  - **共享检索索引**(`search-index.json`):learnings(session 经验)、docs(团队文档)、rules(编码规则)、skills(各 `SKILL.md`)四类,源自团队仓库对应目录,在 `teamai pull` / `teamai contribute` 时构建重建。
@@ -34,12 +34,21 @@ teamai recall --check "<3-6 keywords from the task>"
34
34
  proceed to Step 1–5, do not read any files, do not run a full recall.
35
35
  - If the output starts with `RELEVANT`: check complexity (see below),
36
36
  then continue to Step 1 or take the LOW shortcut.
37
+ `RELEVANT` means only "something scored above the threshold, so reading
38
+ files is worth the cost" — **not** "the knowledge base covers your
39
+ subject". The verdict also reports `threshold=` (the cutoff the score was
40
+ compared against) and, for the top hit, `matched=` / `missing=` listing
41
+ which query terms it covers. Treat `missing=` here as a hint about where
42
+ Step 4 is likely to land, **not** as a reason to stop early: coverage is
43
+ computed over titles and tags only, so a term reported missing may still be
44
+ discussed in a body that a full recall (or a `Grep`) will surface. Only
45
+ `NOT_RELEVANT` short-circuits the flow.
37
46
  - If the command fails or `teamai` is not on PATH: skip the precheck and
38
47
  continue to Step 1 (do not block on precheck failure).
39
48
 
40
49
  #### Complexity quick-judge (after RELEVANT)
41
50
 
42
- > **Format dependency**: The LOW shortcut parses `title=` and `sources=` from `--check` stdout. If `emitCheckVerdict` output format changes, update this section.
51
+ > **Format dependency**: The LOW shortcut parses `title=` and `sources=` from `--check` stdout. The full field set is `<VERDICT> score= threshold=` followed, for a `RELEVANT` hit, by `title="…" [matched=…] [missing=…] [sources=…]`. `title` is quote-delimited and `sources` comes last, so both stay extractable as fields are added. If `emitCheckVerdict` output format changes, update this section.
43
52
 
44
53
  Scan the original task description for complexity signals:
45
54
 
@@ -94,11 +103,13 @@ corresponding file and extract relevant sections. Skip BM25 search.
94
103
  | feature/新功能/新增功能/大功能/redesign/重构整个/multi-file | Feature (large) | `--depth lookup` | Need full file coverage to avoid missing files |
95
104
  | 添加/修改/如何改/实现/implement/refactor | Edit (medium) | `--depth lookup` | Need symbol-level anchors |
96
105
  | bugfix/修复/fix/patch/typo/单文件/one-file | Bugfix (small) | `--depth context` | Fast pass; skip graph-index drill-down |
106
+ | 排查/定位/诊断/为什么/triage/diagnose/investigate | Diagnose (read-only) | `--depth context` | Nothing is being edited, so symbol anchors are not needed |
97
107
 
98
- For **bugfix/small** tasks: use `--depth context` only, skip the
99
- graph-index.json deep read in the edit/change section below, and keep
100
- output ≤ 1500 characters. The main conversation already knows which
101
- file to fix.
108
+ For **bugfix/small** and **diagnose** tasks: use `--depth context` only, skip
109
+ the graph-index.json deep read in the edit/change section below, and keep
110
+ output ≤ 1500 characters. For bugfix the main conversation already knows which
111
+ file to fix; for diagnosis there is no file to fix yet — what is wanted is prior
112
+ experience with the same symptom.
102
113
 
103
114
  **Edit/change queries** (keywords: 新增/添加/修改/如何改/重构/实现; how to add/change/modify/implement): use `--depth lookup` in Step 3 so facts/relation pages are visible. After BM25 recall, also read these directly (bypassing BM25 ranking uncertainty):
104
115
  1. `teamwiki/evidence/code/<project>/.indices/graph-index.json` (priority; fall back to `teamwiki/.indices/graph-index.json` if absent) — when surfacing edges, pick 1–3 entry files most relevant to the task and read only their forward direct-dep edges (`from` == entry file); skip reverse expansion (each edge: `{from, to, relation}` — from/to are file paths, relation is type e.g. DEPENDS_ON)
@@ -115,6 +126,38 @@ none exists, silently skip.
115
126
  Pick 3–6 high-signal keywords from the user query. Strip filler words
116
127
  ("the", "how", "please"). Mix English and Chinese terms when both appear.
117
128
 
129
+ **Lead with the terms that pin down *this* task**: proper nouns, customer or
130
+ product names, service IDs, error codes, versions, symbol names
131
+ (`acme-corp`, `AccountID`, `v2.1.3`, `svc-a1b2c3`, `RuntimeError`), plus the
132
+ specific technology or subsystem (`postgres`, `connection pool`, `oauth`).
133
+
134
+ **Do not let generic troubleshooting words be the bulk of the query.** Words
135
+ describing *any* debugging task — 排查 / 失败 / 问题 / troubleshoot / debug /
136
+ issue / fix and their equivalents in any language — are common in a knowledge
137
+ base where most entries are troubleshooting notes, so a query made mostly of
138
+ them ranks entries by topic rather than by subject. Keep at most one or two as
139
+ supporting terms; do not build the query out of them.
140
+
141
+ **But do not strip them entirely either.** Being common lowers a word's weight;
142
+ it does not make it useless. Entries are often tagged with exactly these words
143
+ (`创建异常`, `现网排查`), so dropping them can push a genuinely relevant entry
144
+ out of the top 5.
145
+
146
+ ```
147
+ task: "acme-corp inference service request failures AccountID error rate triage"
148
+ query: "acme-corp AccountID inference service triage" # kept one supporting term
149
+ ```
150
+
151
+ Note which of your terms are the discriminating ones — you will check
152
+ them against the results in Step 4.
153
+
154
+ If the results look topically right but miss what you asked about, run recall
155
+ once more with a different term mix — swapping which supporting word you keep,
156
+ or trading a proper noun for the subsystem name. Hard rules allow up to three
157
+ calls per invocation; use a second one rather than concluding from a single
158
+ keyword set. `Grep` over the learnings directory is also fair game when a term
159
+ is too specific to rank (see Step 4).
160
+
118
161
  ### Step 3 — Run the teamai recall command
119
162
 
120
163
  Execute with the appropriate depth:
@@ -140,8 +183,37 @@ stop.
140
183
 
141
184
  ### Step 4 — Read the top hits and drill into codebase
142
185
 
143
- For each hit returned by `teamai recall`, read the source file directly
144
- (use `Read`) and condense each into **one or two sentences**.
186
+ **First, judge coverage this is your call, not the CLI's.** Each result
187
+ carries a `Matched: | Missing: …` line listing which of your query terms
188
+ appear in its title or tags (the line is omitted when every term matched).
189
+ Score and `RELEVANT` only tell you a hit is worth opening; they cannot tell
190
+ you whether it covers your subject.
191
+
192
+ If your discriminating terms appear in the `Missing:` list of every result,
193
+ the knowledge base likely has no entry on that specific subject. Verify per the
194
+ judgement rules below, then report the gap using the no-coverage template in
195
+ Step 5 — do not present topically-adjacent entries as answers.
196
+
197
+ Use judgement rather than counting, in both directions:
198
+
199
+ - **A missing term is not proof of absence.** Coverage is computed over titles
200
+ and tags only, so a term can be discussed in the body yet reported missing.
201
+ When a hit looks promising anyway, open the file and decide from its content.
202
+ When a term is specific enough that the index cannot rank it, `Grep` the
203
+ learnings directory for it directly — that reaches body text.
204
+ - **A matched term is not proof of relevance.** Matching is per token, so it
205
+ fires on substrings and on segmented fragments: a query for `AccountID` will
206
+ match an entry about a notification template `ID`, and 客户 (customer) will
207
+ match 客户端 (client). CJK is especially prone to this. Treat `Matched:` on a
208
+ discriminating term as a lead to verify by opening the file, not as a
209
+ conclusion.
210
+ - **Fewer than 5 results does not mean the corpus is thin.** Results are
211
+ deduplicated when title, date, author and content all match, so a learning
212
+ shared twice appears once. Body-
213
+ only matches are also dropped. Both are intentional.
214
+
215
+ For each hit you keep, read the source file directly (use `Read`) and
216
+ condense each into **one or two sentences**.
145
217
 
146
218
  **For codebase hits** (path contains `teamwiki/evidence/`):
147
219
  - If the hit is a raw facts page (component.md, interface.md), prefer
@@ -155,10 +227,15 @@ For each hit returned by `teamai recall`, read the source file directly
155
227
  - If the hit mentions a knowledge gap (from `gaps/detected.md`), relay
156
228
  it to the user: "This area is not fully documented in the knowledge base."
157
229
 
158
- Cap your total summary at ~2000 characters. Drop hits that are off-topic.
230
+ Cap the knowledge summaries at ~2000 characters (the whole response has a
231
+ ~2500 limit, see Hard rules; bugfix and diagnose tasks tighten it to 1500).
232
+ Drop hits that are off-topic.
159
233
 
160
234
  ### Step 5 — Emit a structured response
161
235
 
236
+ Use the numbered-list format below when at least one hit answers the task; use
237
+ the no-coverage variant that follows it when none does.
238
+
162
239
  Return your output in **this exact format** to the main conversation:
163
240
 
164
241
  ```
@@ -209,6 +286,45 @@ If no candidate files section was returned, omit this heading entirely.
209
286
  <!-- teamai:recalled-doc-ids: [<id1>, <id2>, ...] -->
210
287
  ```
211
288
 
289
+ **When nothing covers the subject**, use this variant instead of the numbered
290
+ list — the point is that the main conversation must not mistake topical
291
+ neighbours for answers:
292
+
293
+ ```
294
+ ## Team Knowledge Recall
295
+
296
+ ### Relevant knowledge
297
+
298
+ **No entry covers <discriminating terms>.** <One sentence on what you checked —
299
+ which terms, and whether you grepped bodies as well as titles/tags.>
300
+
301
+ Rejected matches:
302
+ - **[<type>] <doc_id>** — matched <term> only; <why it does not apply>
303
+
304
+ ### Partial coverage (omit if none)
305
+
306
+ 1. **[<type>] <doc_id>** — <file path>
307
+ <which part of the task it covers, and which part it does not>
308
+ Confidence: <high | medium | low>
309
+
310
+ ### Gaps
311
+
312
+ ⚠️ <gap description> — do not guess answers for this area.
313
+ <Point to the tool or skill that would answer it, if one is obvious.>
314
+
315
+ <!-- teamai:recalled-doc-ids: [<only entries listed under Partial coverage>] -->
316
+ ```
317
+
318
+ A task with several requirements is often part-covered: report the covered part
319
+ under **Partial coverage**, say explicitly which requirement it does *not*
320
+ answer, and put the rest under **Gaps**. Rejected entries stay in the rejected
321
+ list — never promote one to answer a requirement it does not address.
322
+
323
+ For a no-coverage response, evidence takes priority over brevity: if listing
324
+ rejected entries pushes past the character cap, allow up to ~2000 characters
325
+ even on bugfix and diagnose tasks, whose 1500 cap this overrides.
326
+ rather than dropping the reasoning.
327
+
212
328
  **Output structure rules:**
213
329
 
214
330
  - `<type>` is one of `skills` / `learnings` / `docs` / `rules` / `codebase`
@@ -232,7 +348,9 @@ If no candidate files section was returned, omit this heading entirely.
232
348
  - **Do not** call `teamai recall` more than 3 times in one invocation.
233
349
  - **Do not** invoke other subagents.
234
350
  - If `teamai` CLI is not on PATH, return `teamai CLI not available` and stop.
235
- - Output total ≤ ~2500 characters. The whole point of using a subagent is
351
+ - Output total ≤ ~2500 characters (≤ 1500 for bugfix and diagnose tasks). This
352
+ is the ceiling for the whole response; the ~2000 in Step 4 applies to the
353
+ knowledge summaries within it. The whole point of using a subagent is
236
354
  to keep the main conversation's context lean.
237
355
  - For codebase hits, **prefer module summaries over raw facts pages** —
238
356
  they give better signal-to-noise for the main conversation.
@@ -243,4 +361,12 @@ If no candidate files section was returned, omit this heading entirely.
243
361
  - When zero hits are found but `teamwiki/` exists, check if the query
244
362
  relates to a known gap before returning "no knowledge found".
245
363
  - When `teamai recall --check` returns `NOT_RELEVANT`, do not continue — return the no-knowledge line and stop. The precheck exists to avoid wasted retrieval on unrelated tasks.
364
+ - **Relevance is your judgement.** `teamai recall` returns its top 5 by score
365
+ without filtering on coverage; it reports `Matched:`/`Missing:` so you can
366
+ decide. Never present hits whose discriminating terms are all missing as if
367
+ they answered the question — report the gap instead. Recall returning
368
+ results is not evidence that the knowledge exists. Equally, a single ranked
369
+ query is not evidence that it does not: before reporting a gap, consider a
370
+ second recall with a different term mix or a `Grep` for the specific term,
371
+ since ranking covers titles and tags while `Grep` reaches bodies.
246
372
  - **Do not invent call relationships.** The "Change entry points" section must be derived solely from graph-index.json edges and dependency-paths.md. If those files are absent or do not cover the queried files, write `relation data not covered` and omit the section — do not guess.