Back to home

outnever

dsh-research-first

Research-first assistant for DeepSeek Harness: gently nudge agents to investigate docs/code/community before editing

Stars
1
Language
JavaScript
Created
Aug 14, 2026
Updated
Aug 14, 2026

Introduction

dsh-research-first

A research-first assistant plugin for DeepSeek Harness (DSH).

Gently nudges the agent to do a cheap, deterministic investigation before editing code — without hard-blocking (so "can't reach docs" never stalls the work).

简体中文

agent about to write/edit/bash without investigating
        │
        ▼
  soft nudge: allow + inject a reminder (model-visible, logged)
        │
  investigation blocked (web_search failed / GitHub unreachable)
        │
        ▼
  remind the user why, offer to continue anyway — fully logged, replayable

Why

Three real failure modes of LLM coding, which compound each other:

FailureSymptom
Guessing before actingWrites code from memory instead of checking requirements / API / docs
Trial-and-error loopsRepeated failures without looking up known community workarounds
Stale knowledgeActs on outdated versions / endpoints that have since changed

The core insight: one cheap lookup prevents one expensive rework.


Design philosophy

Make "verify first" a preferred attempt + frictionless nudge + blocked-notice + full trace, not a hard prerequisite.

Why not hard-block? Investigation can be genuinely impossible (air-gapped environments, network restrictions, no official docs). If "can't verify" halts development, the cure is worse than the disease. So the default is a soft nudge — remind without blocking, leaving the choice to the agent and the user.

BehaviorDescription
Soft nudge (default remind)Editing without investigating → not blocked, but a reminder is injected (model-visible + logged)
Blocked-research detectionInvestigation tools (web_search, etc.) failing → reminder: "research blocked, ask the user whether to continue"
Research-norm injectionAdds "golden research habits" to systemPrompt: search with versions, prefer official tools, explain when blocked
Failure reminderAfter repeated failures, remind to check community feedback (GitHub issues) first
Full traceEvery reminder is a plugin-sourced message in the session log — replayable, auditable

Set intensity: warn (hold for approval) or intensity: block (deny) when you want hard enforcement.


Comparison with similar plugins

PluginFocusDifference from this one
dsh-doublecheckEngineering-discipline gates (grill requirements, red/green tests, adversarial review)Defaults to hard enforcement; this plugin defaults to soft
dsh-pain-point-checkVeto-based stop after failed experimentsIt denies non-investigative tools; this plugin reminds without blocking
dsh-research-firstLightweight research-first assistantFrictionless, non-blocking, hands decisions back to the user when blocked

They compose — use doublecheck for strict discipline, or this plugin for a lightweight, unobtrusive default.


Install

Option 1: official (recommended, needs pnpm)

dsh plugin --profile web add github:outnever/dsh-research-first

Restart:

dsh web

Option 2: manual (no pnpm)

# 1. symlink into the profile's node_modules
ln -sfn /absolute/path/to/dsh-research-first ~/.dsh/profiles/web/node_modules/dsh-research-first

# 2. add to ~/.dsh/profiles/web/cordis.patch.yml:
# - insert:
#     - id: research-first
#       name: 'dsh-research-first'
#       config: { intensity: remind }

# 3. restart dsh web

Verify:

dsh --profile web --dump-config | grep -A2 research-first
# expect: id: research-first / name: dsh-research-first / intensity: remind

Configuration

FieldDefaultMeaning
intensityremindremind (nudge) / warn (approval) / block (deny)
failureThreshold2Consecutive failures before the community-check reminder
injectNormtrueWhether to inject the research norm into systemPrompt
detectBlockedtrueWhether to detect failing investigation tools and remind
investigationToolsread, grep, glob, web_search, read_image, ask_user_question, skillTool names counted as "investigation"
mutationToolswrite, edit, bash, pwsh, str_replace_editorTool names counted as "editing"

How it works

Built on DSH's official extension points only — no private machinery:

  • tools/pre-execute (waterfall): mark investigation / decide allow · remind · deny
  • tools/post-execute (waterfall): inject additionalContexts reminders, detect blocked research, count failures
  • agent/pre-step (waterfall): reset the investigation flag on step===1
  • systemPrompt.section: inject the research norm

Key implementation detail: reminders are hand-written UserMessage shapes ({ id, role:'user', content, source:{kind:'plugin',...} }) with id from Node's built-in crypto.randomUUID(), keeping zero dsh package imports — so the plugin loads via symlink without pnpm resolving dependencies.


Testing

node test.mjs
# 19 mock unit tests: soft nudge, blocked-research, failure reminder, block/warn modes, norm injection, turn reset

Runs with no dependencies — lib/index.js only imports node:crypto.


Known limitations

  • The remind reminder is a soft hint in the session — not enforced; the model may ignore it. Use block to enforce.
  • "Search with versions / prefer official tools" is soft-guided via systemPrompt — rules can't hard-guarantee it (it's ultimately the model's willingness).

Contributing

Issues and PRs welcome. When changing:

  1. Keep zero dsh package imports (prerequisite for symlink loading without pnpm);
  2. Update test.mjs and keep node test.mjs green;
  3. Update the README's behavior description.

License

MIT