Skip to content

fix(recall): search nothing in a project whose config cannot be read (#796) - #798

Merged
jeff-r2026 merged 5 commits into
Tencent:mainfrom
SaulMoro:fix/796-recall-unreadable-config
Sep 24, 2026
Merged

jeff-r2026 merged 5 commits into
Tencent:mainfrom
SaulMoro:fix/796-recall-unreadable-config

Conversation

@SaulMoro

@SaulMoro SaulMoro commented Sep 24, 2026 •

Copy link
Copy Markdown
Collaborator

Fixes #796
Part of #752

#792 is merged (1fd400e); rebased onto origin/main 1fd400e, head 22824a1.

Summary

 teamai recall [--check] "<query>"   (project whose config exists but cannot be read)
+  no query and no --check → "Usage: teamai recall <query>"   (before any detection, as on main)
   detectProjectConfig(cwd, onUnreadable)
-    broken partition skipped → legacy .teamai/ (maybe another team) or user scope
-    search → print results / RELEVANT|NOT_RELEVANT → record recalled counts + quality
+    unreadable → "Nothing was searched: <file>: <reason>. Fix the file, or move it
+                  aside and run `teamai init` to write a new one."   exit 1
+  empty --check → NOT_RELEVANT   (only after detection, so it cannot answer there)
 agents/teamai-recall.md  Step 0 / Step 3
+  output contains "Nothing was searched:" → return that line verbatim, stop,
+    and tell the main conversation to act on it only with the user's consent
 src/builtin-rules.ts  Bash method (tools that run `teamai recall` directly)
+  same instruction

No silent mode: recall has no --silent flag and no hook runs it. A hook that runs recall later should follow pull --silent (#784): print nothing, write the line to ~/.teamai/debug.log, exit 1. skill-data troubleshooting gets one line next to #792's Nothing was synced entry.

Evidence

Real CLI at 58195ab vs the stack base b119ec5 (#792's head). Per provider: team repos are local bare remotes behind an https:// URL, with provider: in teamai.yaml set to git / github / gitlab; teamai init --agent claude,codex,codebuddy,opencode + pull; then the partition config.yaml is broken and another team's legacy .teamai/ put behind it. Agent axis: the recall agent and rule each tool gets deployed, and teamai hook-dispatch … --tool <agent> payloads with the project as cwd.

Case (each of git, github, gitlab) b119ec5 58195ab
recall deployment timeout exit 0, [1/1] [docs] other-team deployment timeout fix exit 1, ✖ Nothing was searched: <partition>/config.yaml: Flow sequence … at line 2, column 1. Fix the file, or move it aside and run `teamai init` to write a new one.
recall --check deployment timeout exit 0, RELEVANT … title="other-team …" exit 1, same line
recall --check '' exit 0, NOT_RELEVANT score=0.0 exit 1, same line
recall '' ✖ Usage: teamai recall <query> same, no detection
recorded after the above votes/alice.yaml, sessions/…-recall-cache.json nothing
deployed teamai-recall agent: .claude/…md, .codex/…toml, .codebuddy/…md, .opencode/…md no refusal relay relays Nothing was searched:
teamai-recall rule: .claude/rules/, .codebuddy/rules/ no refusal relay relays it
hook-dispatch post-tool-use --matcher TodoWrite and stop (transcript with recalled doc-ids), --tool claude/codex/codebuddy/opencode no nudge, no output (#748 gate) same
readable config: recall --check; TodoWrite nudge, four agents RELEVANT title="team-a …"; nudge shown same

Tests (src/__tests__/recall-unreadable-config.test.ts, real configs and index in a sandbox HOME):

broken partition + legacy other-team  → nothing searched/recorded, exit 1, message   ✗ → ✓
broken partition + user scope only     → not searched, exit 1                          ✗ → ✓
--check (query / empty query)          → message, no verdict, exit 1                   ✗ → ✓
missing query                          → usage error, not the refusal                  ✗ → ✓ (CI review)
readable, inheritUserScope, user only, no config → as before                         ✓ → ✓

Earlier, on 5bcb8ee: a live claude -p with the deployed subagent returned the other team's doc before, and the refusal line verbatim after.

Test plan

Rebase to 22824a1 (onto origin/main 1fd400e): own diff unchanged except src/recall.ts. #787 (dc233e4) conflicted there: #796's refusal kept, plus #787's guard that a detection which throws (not a deleted cwd) records no votes; one test commit follows #787's per-scope votes directories and turns #787's broken-project recall test into "nothing searched, nothing recorded". On 22824a1: npx tsc --noEmit, npx vitest run (4674 passed, 1 skipped), npm run build green. No real-CLI rerun: a rebase.

All below on 58195ab:

  • npx tsc --noEmit
  • npx vitest run: 4526 passed, 1 skipped
  • npm run test:e2e: 229 passed, 26 skipped
  • npm run build + the real-CLI matrix above: Claude, Codex, CodeBuddy, OpenCode through their deployed recall agent/rule and hook-dispatch --tool; git, github, gitlab through the team's provider: (local bare remotes; the refusal happens at detection, before any provider API call).

CI review (5812473529)

Finding Outcome
P1 real-CLI matrix incomplete Fixed: matrix above, three providers × four agents
P2 recall.ts:404 detection before the missing-query check Fixed: a missing query is rejected first; only an empty --check still resolves the project, so it cannot print NOT_RELEVANT there
P2 recall.ts:419 silent branch no caller can invoke Fixed: removed with its test; the rule for a future hook is stated in Summary
P2 docs call session-start pull machine-level work Already true after the rebase: #792's b119ec5 still pulls at session start where teamai is not set up and stops only for an unreadable config (pullHandler, src/hook-handlers.ts), which is what docs/usage-guide*.md and CHANGELOG say. Those lines are #792's

Merge Danger

Door: two-way

Blast Radius: narrow

Projects whose config exists but cannot be read: recall <query> and --check fail loudly there instead of answering from another scope. Everywhere else output is unchanged; recall --check '' now runs project detection (including self-mode bootstrap on a fresh single-repo clone), as any recall <query> already did. The recall subcommands (enable/disable/status/feedback/maintenance/promote) still resolve their scope as before; that is a follow-up under #752.

@jeff-r2026 jeff-r2026 self-assigned this Sep 24, 2026
@github-actions

Copy link
Copy Markdown
  • [P1 blocking] Required real-CLI validation is incomplete. The PR test plan explicitly says Codex, OpenCode, CodeBuddy, GitLab, and GitHub were not successfully tested. AGENTS.md requires real-CLI verification to actually pass for Claude, Codex, CodeBuddy, OpenCode and all three providers before the PR.
  • [P2 non-blocking] src/recall.ts:404 resolves project configuration before rejecting a missing query. Consequently, plain teamai recall can run self-mode bootstrap and perform filesystem/network side effects even though the invocation is invalid. Keep the ordinary empty-query check before detection, while retaining early detection specifically for --check.
  • [P2 non-blocking] src/recall.ts:419 adds a silent-mode contract that production cannot invoke: the recall command defines no --silent option and no non-test caller passes silent. The PR body confirms there is currently no such path. Remove this speculative branch and its dedicated test per the repository’s anti-overengineering rule.
  • [P2 non-blocking] docs/usage-guide.md:536, docs/usage-guide.zh-CN.md:501, and CHANGELOG.md:34 still state that session-start pull runs as machine-level work without a resolved config, but src/hook-handlers.ts:108 now returns before pulling whenever config is null. Update all affected documentation to match the new behavior.

@SaulMoro
SaulMoro force-pushed the fix/796-recall-unreadable-config branch from 15309a7 to 58195ab Compare September 24, 2026 11:12
@github-actions

Copy link
Copy Markdown
  • [P2 non-blocking] The PR description still promises an options.silent path and lists its test among “5 red → green” cases, but the final commit removes both (src/recall.ts:404, src/__tests__/recall-unreadable-config.test.ts:179). Update the Summary/Evidence so the documented behavior and test count match the current diff.

Previously reported empty-query ordering, speculative silent implementation, and documentation issues are resolved. The earlier full provider × agent requirement does not apply under the checked-out review rules; the documented representative real-CLI run is sufficient.

@jeff-r2026 jeff-r2026 assigned jeff-r2026 and unassigned jeff-r2026 Sep 24, 2026
@github-actions

Copy link
Copy Markdown

No findings.

  • Previously reported empty-query ordering, speculative silent mode, documentation wording, and PR-description mismatch are resolved.
  • The PR description documents successful build, tests, and representative real-CLI validation, satisfying the review rules.
  • Reviewed the diff only; no PR code was executed.

@SaulMoro
SaulMoro force-pushed the fix/796-recall-unreadable-config branch from 58195ab to b5b5588 Compare September 24, 2026 11:34
@github-actions

Copy link
Copy Markdown

No findings.

  • Previously reported query ordering, speculative silent mode, documentation wording, and PR-description mismatch remain resolved.
  • The PR description includes a successful representative real-CLI matrix; the older commit reference is non-blocking because the rebase was conflict-only.
  • Reviewed only 8cee7ab...b5b5588; no PR code was executed.

@github-actions

Copy link
Copy Markdown

No findings.

  • Previously reported query ordering, speculative silent mode, documentation wording, and PR-description mismatch remain resolved.
  • The PR description includes sufficient tests and representative real-CLI validation. The validation predates merge commit 9a936bb, which is non-blocking under the review rules.
  • Reviewed only the specified diff; no PR code was executed.

…encent#796)

Detection skips a project config it cannot read and returns what loads
next: a legacy .teamai/ behind a broken partition, which may name another
team, or the user scope. recall searched that knowledge, recorded recalled
counts for it, and `recall --check` answered for it; with nothing behind
the broken file it printed NOT_RELEVANT, so the recall subagent told the
member the team had no knowledge and nobody learned the config was broken.

recall() now listens for the unreadable config before anything else,
searches and records nothing, prints the problem with
BROKEN_CONFIG_ADVICE and exits 1, `--check` included. A silent caller
records it in debug.log only, the rule pull follows since Tencent#784. The
teamai-recall agent relays that line instead of skipping the precheck.
- The relayed line ends with "move it aside and run `teamai init`", and
  the main conversation may not have loaded the teamai skill that asks
  for consent first. The recall agent now tells it to show the line to
  the user and not act on it without their consent.
- Tools that run `teamai recall` directly (the Bash method of the recall
  rule, deployed to every tool) get the same instruction.
- CHANGELOG: only the subagent a pull from this release deploys relays
  the line; a project that broke before the upgrade keeps the old one
  until a pull succeeds there.
- The legacy-team test also asserts no votes land in that team's repo.
- CHANGELOG: the entry covers `teamai recall <query>` and `--check`. The
  recall subcommands (enable, disable, status, feedback, maintenance,
  promote) still resolve their scope as before; that is a follow-up.
Reject a missing query before resolving the project, so a bare
`teamai recall` runs no detection (and no self-mode bootstrap). An empty
`--check` still resolves first: it must refuse rather than print
NOT_RELEVANT in a project whose config cannot be read.

Drop the silent branch: `recall` has no --silent flag and no caller
passes `silent`, so it was a contract nothing could invoke.
Tencent#787 moved recalled counts from the shared ~/.teamai/votes/ into each
scope's votes directory, so the Tencent#796 tests look for any votes directory in
the sandbox. Tencent#787's broken-project recall test expected a search to run;
Tencent#796 searches nothing there, which it now asserts, while its checks that no
scope received a vote stay.
@SaulMoro
SaulMoro force-pushed the fix/796-recall-unreadable-config branch from 9a936bb to 22824a1 Compare September 24, 2026 12:15
@github-actions

Copy link
Copy Markdown

No findings.

  • Previously reported query ordering, speculative silent mode, documentation wording, and PR-description mismatch remain resolved.
  • The PR description includes sufficient representative real-CLI validation; testing on an older runtime commit is non-blocking under the review rules.
  • Reviewed only 1fd400e...22824a1; no PR code was executed.

@jeff-r2026
jeff-r2026 merged commit ec56a67 into Tencent:main Sep 24, 2026
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

recall searches nothing in a project whose config cannot be read

2 participants