Skip to content

feat(research): structured ResearchContext — direct tool calls in the research stage (#3372 increment 1)#3806

Merged
williamzujkowski merged 2 commits into
mainfrom
feat/research-context-structured-3372
Jun 9, 2026
Merged

feat(research): structured ResearchContext — direct tool calls in the research stage (#3372 increment 1)#3806
williamzujkowski merged 2 commits into
mainfrom
feat/research-context-structured-3372

Conversation

@williamzujkowski

Copy link
Copy Markdown
Collaborator

Closes #3372 (increment 1). Unblocks #3234 once increment 2 lands.

Decision (7/7 higher_order consensus vote → Option A)

The research stage routed through two LLM experts that called research_discover/research_analyze and returned only text — the structured DiscoveredItem[] (relevanceScore), recommendations, and quality signals were discarded (agent-executor.ts:455). The vote chose Option A: call the tools directly for structure and derive the text deterministically from that same structure (single source of truth). Rejected B (re-running the query twice → divergent text-vs-metadata) and C (invasive expert-bridge change).

Change (increment 1)

  • New pure module pipeline/research-context.ts: maps ResearchDiscoverResponse + analyze recommendationsResearchContext { text, metadata: { discoveredItems(relevanceScore), recommendations, qualitySignals } }. Text is rendered deterministically from the metadata; external titles/recommendations are escaped (backticks/control-chars/newlines neutralized) and the rendered list is bounded (security-voter conditions). 7 unit tests.
  • Research stage (agent-executor.ts) now calls executeDiscovery + analyzeGaps directly (no research-stage LLM tokens), builds the context, and returns its structure-derived text. research() signature unchanged this increment (returns string) → zero churn to the ~6 stage-mocking test files. Fail-safe try/catch; prior-learnings memory context still appended (feat(pipeline): wire memory system into dev pipeline — query + write-back #1716).
  • analyzeGaps exported from research-analyze.ts (deterministic — registry-derived, no LLM).
  • Research-stage tests rewritten to mock the direct calls + assert the deterministic structured text.

Verification (full gate set)

628 pipeline tests · governance (46 tools) · description-drift · docs:tools (47) · registry-coverage · producer-consumer (the new module has its consumer) · typecheck · lint — all green.

Next (increment 2, tracked on #3372/#3234)

Thread the ResearchContext metadata through research()→plan()→vote() (DevPipelineStages signature change) + weight voter-prompts.ts on research maturity (the consumer the vote requires) + instrument vote outcomes. That unblocks #3234.

🤖 Generated with Claude Code

williamzujkowski and others added 2 commits June 9, 2026 12:23
…istic renderer (#3372 increment 1, WIP)

Per the 7/7 higher_order vote (Option A): pure module that maps a research-tool
ResearchDiscoverResponse + analyze recommendations into structured ResearchContext
{ text, metadata: { discoveredItems(relevanceScore), recommendations,
qualitySignals } }, with the human-readable text DERIVED deterministically from the
metadata (single source of truth) and external titles/recommendations escaped +
bounded (security-voter condition). 7 tests; typecheck + lint clean.

WIP — the consumer (rewire the research stage to call executeDiscovery + analyzeGaps
directly and return this text) lands in the next commit; NOT yet a mergeable PR
(producer-consumer gate needs the consumer). Branch persists for completion.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
… increment 1)

Completes increment 1 (the core ResearchContext module landed in the prior commit).
Per the 7/7 higher_order vote (Option A):
- research stage (agent-executor.ts) calls executeDiscovery + analyzeGaps DIRECTLY
  instead of two LLM experts that discard the structure; builds the ResearchContext
  and returns its deterministic, structure-derived text (signature unchanged — no
  DevPipelineStages churn this increment). Fail-safe try/catch. Prior-learnings
  memory context is appended to the text (preserved from #1716).
- export analyzeGaps from research-analyze.ts (deterministic, registry-derived).
- agent-executor.test.ts: research-stage tests now mock executeDiscovery/analyzeGaps
  and assert the direct calls + deterministic structured text (was the LLM path).

Full gate set green: 628 pipeline tests, governance (46 tools), description-drift,
docs:tools (47), registry-coverage, producer-consumer (module now has its consumer),
typecheck + lint.

Closes #3372 (increment 1; increment 2 threads metadata through plan/vote — tracked).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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.

Pass structured ResearchContext (not just text) to plan/vote — #3258 Option B follow-up

1 participant