Repository navigation
Route questions about stored knowledge as lookups and search before answering (closes #3265) - #3480
Conversation
Pragmatic Code Review — PR #3480 (issue #3265)Review Type: Initial Review Verdict: REQUEST CHANGES. The change is a clear net improvement and has no security or data-integrity problem. Three things should be settled before merge: acceptance criterion 6 is only half met and one new live test pins the opposite of it; criterion 2 has no recorded evidence yet; and one accompanying doc names a constant that doesn't exist. Reviewed by reading the three-dot diff ( Requirements Check
Code Review Findings🟡 Important1. "Find the skill for X" is routed into the search the skill list says never to run
2. Stage 2 can still ask the user before searching on a lookup turn
3. The conversation exclusion can return zero rows when matching notes exist
4. Every lookup turn's first reply is discarded, with no control for questions the conversation answers
5.
🟢 Suggestions6. "In full" and "the complete document" overstate what the model receives
7. Tests that would pin claims the PR makes
8.
Nitpicks
What holds up
RecommendationREQUEST CHANGES Before merge:
Findings 2 and 3 are small and worth doing in this PR. Finding 4 needs at least the live control. The rest is optional. Also still open on the PR's own test plan: |
malibio
left a comment
There was a problem hiding this comment.
Automated pragmatic-code-review: REQUEST CHANGES (posted as a comment — GitHub blocks self-approval). Full findings in the review comment above.
Address-review summary (commit
|
Pragmatic Code Review — PR #3480 (issue #3265)Review Type: Re-Review Verdict: COMMENT. The commit Scope: Previous Review Summary
Status of each previous finding
What I checked on the three risky changesRefetch loop ( Held streaming (
New Findings1. [Important] The replay of a held round that stands has no test
2. [Important] The cost of a follow-up being treated as a lookup is recorded but not measured
3. [Suggestion] The rule is enforced on the tool surface, not at dispatch, and for the whole turn
4. [Suggestion] Each refetch starts again from the first row
5. [Suggestion]
Nitpicks
Docs
Merge conditionsNot findings; the main agent already has the first one queued.
RecommendationCOMMENT The code is sound and the fixes are real. New findings 1 and 2 are small and worth doing before the eval run, since finding 2's scenario belongs in it. Findings 3 to 5 and the nits are optional. |
malibio
left a comment
There was a problem hiding this comment.
Automated pragmatic-code-review (re-review): COMMENT. Full findings in the review comment above.
Address-review summary, round 2 (commit
|
Eval evidence on the final build (commit
|
| Scenario | Result | Tools |
|---|---|---|
skill-find-request |
pass | search_semantic |
skill-question-how |
pass | search_semantic |
skill-question-what |
pass | search_semantic |
skill-question-explain |
pass | search_semantic |
outcome-question-searches-first |
pass | search_semantic |
op-own-skills-no-search |
pass | none |
outcome-find-own-skill |
pass | search_semantic, reply names Research & Search |
outcome-follow-up-keeps-its-answer |
pass | none |
op-list-by-type |
pass | search_nodes |
schema-shared-name-signed |
pass | search_nodes |
This is a partial run (--only), so it is evidence for these scenarios and not a full-suite score.
eval:routing (full): 18/19
- The one failure is
indirect-schema-freelance("start tracking our planning cycles" creates a node instead of a schema). It failed in every run on this branch, including the first one before any routing change, and Research & Search is not among its candidates. - Clarification scenarios (
ambiguous-client-contacts,ambiguous-manage-projects,clarification-then-fallthrough), both compound scenarios and both single-intent-at-length scenarios pass.
Two failures the previous run found, and what fixed them (commit 60cc35a0)
The previous run on the merged build scored 8/10 on the same selection.
outcome-question-searches-firstfailed. After two turns that set up record types, Stage 1 routed "How do we decide which venue gets a deposit refund?" as a query, so the turn was never treated as a lookup and replied "I do not have a tool or information". Reproduced in the live Stage 1 check at 3 of 3. No wording of the routing tools fixed it without breaking the compound split or a find request (five variants measured). Fix: a question-shaped message is put to Stage 1 by itself first; a lookup from that pass stands, anything else is decided on the blended view as before. Live check after the fix: 21 of 21 questions asked after unrelated turns route as lookups, and question-shaped write requests still route as queries.outcome-follow-up-keeps-its-answerfailed. The model answered correctly, then the clarification contract's re-prompt (a chat that has only asked questions counts as already clarified) replaced it, and the second reply was "I'm not sure what you mean". Fix: the re-prompt counts only when it produces a call; otherwise the first reply stands and the re-prompt is removed from the history.
Both changes are in the agent loop and came after the last review, so I am requesting a re-review of 375b2c51..HEAD.
Also verified
cargo nextest -p nodespace-agent: 892 pass; clippy clean.- Live Stage 1 checks on the locked model: 7 of 7 pass.
Pragmatic Code Review — PR #3480 (issue #3265)Review Type: Re-Review (2) Verdict: COMMENT. Scope: Previous Review Summary
Status of each previous finding
Merge conflict resolutionsAll five look right.
What I checked on the two new behavioursTwo-pass routing (
Keeping the first reply (
New Findings1. [Important] A question-shaped answer to a clarification can be routed as a lookup
2. [Important] A question that needs its context is unmeasured, and the diagnostic no longer follows the loop
3. [Important] The unit test for "routed on the message alone" passes without the change
4. [Suggestion] A lookup that is not shaped like a question is still routed on the blended view only
5. [Suggestion] The text log does not say which view decided or how many passes ran
6. [Suggestion] The second reply is still streamed, then replaced
7. [Suggestion] In an intent with a composed clarification, the kept reply is the repeated question
8. [Suggestion] A dropped
Nitpicks
Docs
Requirements check
RecommendationCOMMENT The work is a net improvement and the eval evidence supports the acceptance criteria. I would approve once finding 1 has its guard and test, finding 3's test asserts what Stage 1 was shown, and finding 2's cases have been run through the live helper with the result recorded. Findings 4 to 8 and the nits are optional. A full |
malibio
left a comment
There was a problem hiding this comment.
Automated pragmatic-code-review (re-review 2): COMMENT (posted as a comment — GitHub blocks self-approval). Full findings in the review comment above.
Address-review, round 3 (after re-review 2)Head is now Addressed from re-review 2
Changed since, from eval findings
Merges of
|
Pragmatic Code Review — PR #3480 (issue #3265)Review Type: Re-Review (3) Verdict: COMMENT. Re-review 2's findings are addressed, and the six later commits are each a reasonable answer to a measured failure. I am not approving because the fix for "the second reply is streamed, then replaced" introduced a streaming regression on the neighbouring path (finding 1, a one-line fix), the new id-grounding rule rests on a statement about system messages that is not true of one of them (finding 2), and half of the newest condition in the loop has no test that fails without it (finding 3). Scope: I ran no builds, tests, live tests or evals, as instructed. Everything below about what a test pins, and about runtime behaviour, is from reading the code. I did not revert a change and watch a test fail. Previous Review Summary
Status of each re-review 2 finding
Merge resolutionsAll six look right.
New Findings1. [Important] After a re-prompt that works, the final answer is never streamed
2. [Important] System messages are not all written from tool results: the conversation summary is the model's
3. [Important] Half of the new re-prompt condition has no test that fails without it
4. [Suggestion]
5. [Suggestion]
6. [Suggestion] The own-skills fix does not hold in an intent with a composed clarification
7. [Suggestion] The grounding test uses a hand-written copy of the daemon's record
8. [Suggestion] With
Nitpicks
What I checked and found sound
DocsOnly
Requirements check
RecommendationCOMMENT The branch is a net improvement and the acceptance criteria are met on the posted evidence. I would approve once finding 1 has its one-line fix and a streaming assertion, finding 2's summary message is excluded or its ids are system-written, and finding 3's test exists. Findings 4 to 8 and the nits are optional. The full |
malibio
left a comment
There was a problem hiding this comment.
Automated pragmatic-code-review (re-review 3): COMMENT (posted as a comment — GitHub blocks self-approval). Full findings in the review comment above.
Address-review, round 4 (after re-review 3)Head is Addressed
Not changed
Verification
Re-Review DecisionDecision: RE-REVIEW NEEDED Rationale: Findings 1 and 2 changed loop behaviour (when a held round is released, which system messages ground an id). The change is small, but it is in the code path the last three rounds each found something in. |
Pragmatic Code Review — PR #3480 (issue #3265)Review Type: Re-Review (4) Verdict: APPROVE. The three Important findings from re-review 3 are fixed, each with a test that fails without its fix as far as I can read them. I traced every combination of the two holds and found no round that is held and never forwarded, and none forwarded twice. Nothing below blocks the merge. The one finding worth a few minutes before merging is finding 1: the new eval scenario probably does not reach the path its comment says it measures. Scope: I ran no builds, tests or evals, as instructed. Statements about what a test pins are from reading the code; I did not revert a fix and watch a test fail. Previous Review Summary
Status of each re-review 3 finding
The holds: paths traced
The re-prompt requires New Findings1. [Suggestion] The new eval scenario probably does not reach the put-back its comment describes
2. [Suggestion] The streaming test would pass if the answer were forwarded twice
3. [Suggestion] The grounding sentences were inserted in the middle of the skill-list paragraph
4. [Suggestion] Excluding the summary also drops real ids, and the comment says otherwise
Nitpicks
What I checked and found sound
RecommendationAPPROVE No finding is blocking. Findings 1 to 4 are small and local; 1 and 3 are the two I would do before merging, since 1 decides whether the new scenario measures anything and 3 is a sentence in the docs that now says the wrong thing. |
malibio
left a comment
There was a problem hiding this comment.
Automated pragmatic-code-review (re-review 4): APPROVE (posted as a comment — GitHub blocks self-approval). Full findings in the review comment above.
Address-review, round 5 (after re-review 4: APPROVE)Head is
Not changed: the harness does not print a marker for the two "Clarification contract" log lines, so a scenario cannot assert which path it took; the Verification
Re-Review DecisionDecision: NO RE-REVIEW NEEDED Rationale: Re-review 4 approved with nothing blocking. The one commit since changes no production logic: a tighter test assertion, comments, one eval fixture's prior turns, and docs. |
|
Merge queue: #3480 was taken out of the queue — it conflicts with main in: packages/agent/src/local_agent/agent_loop.rs, packages/agent/src/local_agent/tools.rs, packages/agent/src/skill_pipeline.rs, packages/agent/tests/golden/prompt_assembly/stage1_request.golden, packages/agent/tests/it/live_stage1_golden_prompts.rs, packages/agent/tests/it/prompt_assembly_snapshot.rs, packages/core/src/services/embedding_service.rs, scripts/eval/fixtures/decisions.test.ts, scripts/eval/fixtures/decisions.ts. Rebase onto origin/main, push, and re-run |
09c8f35 to
790c37b
Compare
…answering (closes #3265) A question about what the user has stored was mishandled at every stage: Stage 1 clarified it or kept only its topic, retrieval matched the topic to whichever skill shared a noun with it, Stage 2 answered from the conversation or asked for context without searching, and a search returned the chat the question was asked in. - Stage 1 has a fourth structural choice, route_lookup, for a question or a request to find something. A lookup-shaped message in a chat with history is asked about by itself first, since blended with earlier turns a question took on the chat's subject. - Retrieval is asked for the capability and then the topic. Research & Search's description carries retrieval and question vocabulary, and a mutating fourth candidate is kept when a read-only skill places without leading. - A lookup is always searched before the user sees a reply: if Stage 2 makes no call, the system runs the search. A lookup turn never offers route_clarify. Explanatory questions read the top three results. - search_nodes and search_semantic do not return conversations, resolved through the type registry. - Stage 2 is shown the skill list on question-shaped turns, so a question about the agent's own skills is answered from it. - The clarification re-prompt keeps the first reply when it produces no call in an intent that composed no clarification, and is skipped for a question there. A node id is grounded by the system's record of an earlier turn as well as by a tool message, and never by the conversation summary. - Eval harness: --only and --list for partial runs, knowledge-question scenarios, and reading the daemon log across a rotation. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
790c37b to
07f8fd8
Compare
Closes #3265.
What was wrong
A question about the user's own knowledge failed at four layers, traced on the locked model (Gemma 4 E4B):
route_clarify("Are you asking about the concept of 'merge gate' … or a physical object?"); the rest kept only the topic.search_nodesreturned the chat itself, titled from the user's question.What changed
route_lookup, a fourth Stage 1 choice, for a question or a request to find something. It carries the topic; the system retrieves skills withsearch stored knowledge for <topic>. Research & Search's description carries that phrase and the retrieval verbs a user says.search_semanticon the topic (three results in full) and the model answers from the results. A prose re-prompt was measured first and changed nothing: the model repeated "I do not have a tool or information regarding that".routing::select_candidates, at most one extra). The search skill's broader vocabulary had pushed Schema Creation to fourth on "keep track of decisions behind each feature".search_nodesnever returns a conversation (resolved through the type registry, subtypes included), andsearch_semanticresults now carry each node's type.--only <id,id,...>and--liston every eval;eval:decisionsgains six question scenarios.Measured
Live, on the locked models:
live_stage1_golden_prompts): 17 of 17 questions and find requests route as a lookup; writes stay queries; a write plus a lookup is split withroute_multi; vague requests still clarify; questions about the agent route as a query. Stable across three runs.live_skill_retrieval_stability): 21 guards pass, including 14 lookups at rank 1 and every pre-existing routing guard.eval:decisions(selected scenarios): the search-before-answering scenario, the skills question, and both existing question-phrased scenarios pass.eval:routing: see the comment below for the run on the final build.Notes for review
route_lookup's description is load-bearing: without it, the tool's presence stopped the model splitting a compound request and stopped it clarifying "help me manage our roadmap". Both are now pinned by live tests.exclusionon Research & Search was tried for the displacement problem and rejected: it also dropped the skill out of the top 3 on short lookups.nodespace-docshas matching changes toprompt-skill-system.md,data-layer.md, ADR-038 andagent-eval.md, committed alongside the merge.Test plan
cargo nextest -p nodespace-agent: 855 passbun run test:scripts,bun run test:skill, SKILL.md drift and size checkseval:routingand selectedeval:decisionson the final buildbun run test:changed🤖 Generated with Claude Code