Skip to content

Latest commit

 

History

History
161 lines (135 loc) · 9.43 KB

conversation-research.md

File metadata and controls

161 lines (135 loc) · 9.43 KB

Research offers from Chat

With CONVERSATION_PLAN=on, ordinary human Chat messages can propose external research. A message may explicitly suggest investigation or identify a meaningful information gap. The subject can be stated directly or resolved from bounded recent discussion and decision context. The classifier favors clear opportunities; ambiguous subjects and repository-only debugging questions are left unapplied.

Decision analysis and research analysis run independently. Research does not need an existing decision, known candidate options, or an accepted decision contribution. A message can contribute to a decision and propose research at the same time.

Offer lifecycle

An offer appears in Chat with Start research, Edit brief, and Dismiss. The brief is synthesized from its source material through an isolated harness worker. When synthesis is unavailable, a self-contained source excerpt can serve as the initial brief. An offer without a usable brief remains internal until preparation succeeds. An offer is not yet a research request or a child document.

Any repository writer can edit, start, or dismiss an offer. These actions are shared with the other participants:

  • New relevant discussion refreshes an untouched brief.
  • Entering the shared editor gives people control of its wording. Subsequent discussion produces optional sourced additions instead of rewriting the brief.
  • The editor is live-collaborative; Done closes the editor after its edits have entered the shared draft. Unacknowledged edits are retained for reconnect.
  • The single card moves beneath the latest message that materially contributes to it. Its original source and identity remain stable.
  • Repeated discussion reuses an existing offer. A dismissed topic can return after a fresh explicit research proposal or materially changed scope.
  • Additional requirements after acceptance can produce a linked follow-up offer.

Start research accepts the latest server-accepted shared draft. The initiating browser first flushes its own pending edits. The server then atomically seals the current brief and records the durable start intent. Edits arriving after that boundary are excluded. Research creation and execution follow through idempotent delivery, using an immutable offer-scoped key. Simultaneous starters observe the same result and the winning participant's attribution.

The card shows request progress and opens the ordinary child document once the complete report has been published. Failure and retry preserve the accepted brief. See background jobs for research execution and child publication. The existing /research document composer remains the manual entry.

While research runs, Chat also shows its current code-owned worker activity, such as waiting for a web-search response or waiting for the model's findings. A failed request exposes its safe failure explanation and Retry research in the same card. Retrying keeps the accepted brief and request identity.

Processing and persistence

Both analysis queues commit with the saved message. Each has independent outcomes and retry receipts. Model work runs outside the document mutation lock; research admission rechecks affected offers and decisions before committing. A failure in one analysis path does not roll back the other's accepted changes.

Research uses its own versioned Jev question set. The decision classifier no longer asks research_need. Historical analyses retain that field when present. The message diagnostics show research judgments, policy outcomes, model and question-set versions, admission-policy version, timing, and an independent retry action. Admission checks show the score and actual minimum or maximum used. Subject clarity combines the explicit and contextual probabilities; the winning category's confidence is a separate model judgment.

Admission policy research-admission-2 uses a 70% external-suitability minimum when the explicit-proposal signal is at least 90%. Inferred opportunities use 80%. A proposal still needs sufficient research significance, speaker ownership, a clear subject, valid source evidence, and an unresolved question. Updates to an existing offer can establish significance through a material scope change. Only the external-suitability minimum responds to strong explicit intent. Failures report the unmet threshold rather than labeling a borderline score as proof that a request is not external research. Historical analyses without the new admission fields retain their original diagnostics.

Conversation state version two adds research analysis and general offer metadata inside the existing version-one channel sidecar. Restoration upgrades unfinished version-one work without reanalyzing completed chat. Historical pricing offers keep their original option-snapshot validation and request identities.

Brief drafts are bounded json-joy string CRDTs from packages/draft. The server validates candidate patches and persists their complete state before acknowledgement or publication. Original excerpts, generated wording, and human edits remain distinct. Offer placement is presentation metadata and never determines request identity.

research-brief@1 uses the generic durable job framework. It receives selected Chat excerpts and decision snapshots, returns structured output with source IDs, and has no web, repository, shell, or document-editing tools. Generation checks prevent stale output from replacing human edits or accepted briefs. Successful artifacts reconcile on completion or the next room opening. Runner failures also reconcile the offer immediately so its refinement error and retry action become visible. The brief worker uses a 30-credit session ceiling, matching the Copilot SDK's minimum accepted session limit.

Configuration

  • CONVERSATION_PLAN=on enables both Jev analysis paths; the default is off.
  • DECISIONS_MODEL and DECISIONS_TIMEOUT_MS configure the classifier both paths share; see Decisions.
  • Brief synthesis uses the existing harness and active Planner owner. Passive synthesis does not claim ownership.
  • AGENT=off or BACKGROUND_JOBS=off disables synthesis. Source-based offers can still appear. Starting research follows the existing execution capability and authorization checks; unavailable execution is shown in the card.
  • Offers and research execution are supported on top-level documents. Child documents do not offer another research level.

Verification

The relevant checks include:

bun test packages/draft apps/server/src/conversation-plan apps/server/src/jobs
bun run types
bun run ci
bun run build
bun --bun node_modules/@playwright/test/cli.js test --config e2e/source/playwright.config.ts research-offers.native.ts
E2E_RESEARCH_OFFERS=1 bun run e2e research-conversation.e2e.ts --project chromium --workers 1

The application test switch selects the Jev HTTP fixture and keeps research execution off. It exercises production authentication, sockets, persistence, classification admission, shared editing, source movement, and dismissal. Unit and storage tests cover accepted-brief delivery and request identity. The PostgreSQL conversation reconstruction test uses fresh processes to verify sealed drafts and pending delivery survive restart.

Provider fixtures establish mechanics, not live semantic accuracy. Live checks should cover paraphrases, implied subjects, comparisons, information gaps, negation, reported speech, withdrawal, and unrelated discussion, recording the actual Jev model version and both missed and unnecessary suggestions.

A bounded live check on 5 October 2026 used jev-1.13.0 for 16 initial-message cases and a four-message offer lifecycle. The final pass recognized the original “maybe we should investigate Jev alternatives” example, contextual shorthand, pricing gaps, and general comparisons; it withheld offers for ambiguous subjects, repository-only questions, negation, reported speech, and withdrawal. The lifecycle pass retained one offer while adding a self-hosting requirement and allowed a fresh explicit proposal after dismissal. These observations cover classification and admission, not live execution of the report-generation workers.

A follow-up admission-policy check on 6 October used 36 scenarios twice, including 12 held-out scenarios, with jev-1.13.0. All 36 negative runs were withheld and 32 of 36 positive runs produced research candidates. The four misses were bare references to Jev falling below the independent subject-clarity threshold. The exact reported question passed in two additional runs with recent discussion identifying TypeSafe Jev's role. A deterministic regression covers the reported 79% external-suitability score with strong intent and explicitly clear subject probabilities; that score now passes the explicit-proposal path. These results do not establish that every paraphrase will pass the other admission gates.

A live execution check on 6 October under copilot-sdk with gpt-6-luna successfully refined an existing offer. Retrying its accepted research request completed MCP setup, opened the model session, and passed search authorization, but the web_search call remained unresolved for 60 seconds. The request failed with web-search-timeout, retaining its identity and sealed brief. This confirms the bounded failure and retry path; successful report publication for that request remains unverified. The diagnostics locate the delay inside the MCP call but do not establish whether its cause is the transport or remote service.