跪拜 Guibai
← Back to the summary

DeepSeek's dsh-superagent: A Research Prototype That Turns 'Take Less Attention' Into Executable Rules

Introduction

An agent that can do the work of an entire team can also waste the attention of that entire team.

This is the 253rd article in the "One Open Source Project a Day" series. Today we look at dsh-superagent (deepseek-ai/dsh-superagent-prototype).

First, the disclaimer at the top of the README, because it matters: this is a research prototype for reference only, not an official DeepSeek product. The code comes from the team's daily development, much of it written by coding agents; it is not identical to the internal version, nor to the implementation described in the paper Exploring Super-agent Design: Towards a More Autonomous Agent System. Some designs discussed in the paper are future directions and are not implemented in the prototype.

So where is the value? Not in code maturity, but in the design documents. Nine sequentially numbered documents in the repo spell out in concrete detail what restraint means for an agent that works proactively: when it should act, when it must stay silent, how permissions are granted and revoked, and how a ticket starts, continues, and ends.

What you will learn

Prerequisites


Project Background

Project Overview

dsh-superagent is a proactive coding agent that watches a single GitHub repository, packaged as a bundle for DeepSeek Harness (DSH).

From the README: it listens on GitHub, and also on Feishu. When a permitted person makes a work request, it opens a ticket, works in its own Agent Session and directory, and replies in the original conversation, typically with a Pull Request. The web panel only shows what needs human attention.

About DeepSeek Harness: the official site says it is DeepSeek's open-source harness built on Cordis's "everything is a plugin" architecture. It runs as a desktop app or launches a web UI from code, and is currently in global public preview. dsh-superagent is a plugin bundle in that ecosystem.

Author and Team

Project Data

Data from GitHub on 2026-11-03, for reference:


Main Features

Core Workflow

The agent runs this pipeline:

  1. Listen: GitHub notifications, subscribed issues and PRs, CI changes, PR merges or closes; Feishu real-time events and topic polling
  2. Judge: a permitted person explicitly @mentions it is required for a request; for work no one asked for, the team must write rules
  3. Work: opens a ticket per request, giving it a dedicated Executor Session and a dedicated directory
  4. Deliver: returns results to the original conversation, typically a Pull Request
  5. Panel: the web panel lists only what needs human handling; health status stays out of the way

Use Cases

  1. Small day-to-day tasks in a team repo

    • Mention @agent request in an issue; a ticket appears in about a minute, followed by a confirmation reply and later a PR
  2. Requests in a Feishu group

    • After configuring a bot, permitted users mention it in the group
  3. Follow-up after PR review

    • Review comments and CI results come back to the ticket via subscriptions, and the agent keeps iterating
  4. Proactive work according to team rules

    • For example, write rules to handle certain dependency updates; first run in observe mode to record "what it would have accepted", then switch to auto once it looks reliable
  5. Managing the agent as a teammate

    • The panel shows todos, approvals, retries, and pauses, instead of log-watching

Quick Start

The official approach is itself interesting: there are many setup steps, so let an agent walk you through them.

To your coding agent say:

Read SETUP.md in this repository and set up dsh-superagent with me.

SETUP.md is an installation guide written for an agent. It dictates that the setup agent also follows "take less attention":

The questioning order follows the domain model: first where requests come from (GitHub only or also Feishu, which repo, which GitHub account), then who can make requests, then how the agent handles tickets (local clone location, commit identity, whether to auto-merge).

Conservative defaults:

An example manual profile is short:

- id: webserver
  config:
    host: 127.0.0.1
    port: 3082
- id: dsh-superagent
  config:
    stateDir: <absolute path, e.g. /home/me/.dsh/state/superagent>
# Optional Feishu
# - id: dsh-superagent-feishu
#   disabled: false

Developer command: pnpm check runs type checks, tests, and build in sequence.

Core Features

  1. Act only when asked or permitted by rules

    • Requests must directly name the agent and come from a permitted team member
  2. Speak only when someone must act or a result is useful

    • Confirm once, stay quiet while working, then message only for results, decisions needed, or failure
  3. Ask one concrete question at a time

    • Use structured fields so the question reaches the human clearly, instead of being buried in long reports
  4. Stop based on impact, not effort

    • Local changes go up to reviewable results; changes needing design decisions stop and ask
  5. Honest reporting

    • Drafts are marked incomplete, failures are reported as failures, limits are not circumvented but raised as questions
  6. Team shapes behavior through text

    • Three team prompt blocks (communication, ticket scope, delivery requirements) plus team skills cover most needs

Project Advantages

Comparison dsh-superagent Manually directing a coding agent in a terminal Common GitHub bots
Trigger Mention in issue/group, async Human at terminal Fixed event triggers
Permission boundary Whitelist + authorization records + admission table enforced by host Depends on current session Depends on script
Proactivity Yes, but defaults to recording; rules must be written by team None Yes, but hardcoded logic
Human interruption Design goal is to minimize None Often noisy
Auditability Panel traces Trigger -> Eval -> Ticket Terminal history Logs

Why read it?


Detailed Project Analysis

One-Sentence Philosophy: Attention is a Cost

docs/000-philosophy.md is only three kilobytes, but the entire project unfolds from it:

Take as little human attention as possible, and give as much value as possible.

Every message, notification, question, setting, panel element, even a piece of documentation, costs someone attention. Each one must deliver more value than it costs, or be removed.

This principle yields requirements for the agent (listed above under Core Features) and for the design itself:

The final section, "Responsibility", is blunt: the agent comments, opens PRs, and sends messages under an account the team sees every day; every message it sends consumes colleagues' attention, and the operator is responsible.

Final line: "The goal is to give the right help at the right time, and do nothing otherwise."

Domain Model: From Trigger to Ticket

docs/001-domain.md defines the entire conceptual set. The main flow:

Work flows from Trigger to Eval and then to execution. Source produces Trigger; Trigger fans out as context to Tickets subscribed to its Thread. Messages from a person reaching a given Ticket stay with that Ticket; all other Triggers go to Eval, which decides whether they are new work requests. When Eval accepts, it creates a Ticket with a Mandate. Assignment hands the Ticket to an Executor; results return to Source through a Channel.

Core concepts:

Concept Meaning Rules it holds
Source Event stream, e.g. GitHub or Feishu Saves its own read cursor and bot identity; discards its own bot's messages; restart must not replay events
Trigger An immutable event Accepting it twice still creates one Ticket; unit of audit and idempotency
Thread Triggers ordered by time At most one Eval at a time; can hold multiple Tickets
Channel Write end of a Thread Confirmations, replies, PRs, resolved reviews are writes
Policy Versioned evaluation rules plus per-Source parts (who can start work, etc.) If rules change, running Evals must be discarded
Eval Judgment over a batch of Triggers, split into admission and reasoning layers Stateless; outputs a Decision
Mandate Granted on acceptance: policy version, scope, intensity, match rules, sender identity Immutable; widening scope requires a new Ticket; only a human stop can revoke it
Ticket An authorized unit of work Only Eval can create it; has its own state, not tied to Executor
Assignment Binding of Ticket to an Executor instance A Ticket can have multiple Assignments over time
Subscription Many-to-many between Ticket and Thread Later discussion reaches the executor without needing another mention

Two designs worth pausing on.

First, "person" is not a domain concept. Triggers carry a sender identifier from the Source; the whitelist is part of Policy for a specific Source, using that Source's identity system. The fact that the same person has different accounts on GitHub and Feishu is prompt text the agent reads when needed, not a cross-Source identity mapping table.

Second, the document has a dedicated section "Rejected Concepts" recording options that were not adopted and why, for example:

Rejected Reason
Tie Ticket state to DSH Session Tickets can be handed off, recovered, or run by multiple Executors, so they define their own state
Executor claims "a human told me to stop" Only Eval decides termination intensity
Cancel running Tickets when policy changes Cancellation leaves partial work; record the change and deliver it instead
Infer "waiting on human" from free text in reports Classification needs structured facts; Executor asks questions with structured fields
At most one active Ticket per Thread A Thread may contain several independent matters

Writing down "what we don't do and why" is something many projects lack.

Authorization and Admission: Who Can Get It Working

docs/002-authorization.md opens with a tone-setting line:

Hosts enforce whitelists, rules, and Mandates. Messages, comments, and referenced documents are inputs to decisions and cannot change these permissions.

Triggers take two paths:

Intensity comes in two levels:

Intensity Situation
explicit A whitelisted person mentions the agent, or follows up in the Thread of an existing Ticket; admission-table cells marked as explicit requests
inferred A non-whitelisted person follows up in a Thread with a Ticket; admission-table cells marked as inferred candidates; whitelisted bots' messages
not admitted Other bots, anything the admission table ignores, and all inferred cases when intake mode is off

Intake mode is part of Policy:

Mode Effect
off No inferred candidate can become a candidate
observe (default) Inferred candidates are evaluated; those that pass are recorded as "would have accepted" and ignored, not accepted
auto Inferred candidates that pass evaluation are accepted

Explicit requests work in all modes. Run in observe first, review recorded decisions, then switch to auto. Every evaluation checks each enabled rule; proactive acceptance requires at least one matching rule.

What happens when rules change is also covered: a Policy change discards running Evals and re-queues them, and sends a "policy changed" input to affected active Tickets, stating whether the matching rule changed, the requester is no longer permitted, or proactive work is no longer accepted. It does not immediately revoke Mandates of existing Tickets. Only when a finished Ticket is restored is it re-validated against current Policy:

If validation fails, the Ticket stays finished, and each of its waiting messages is treated as "did not reach any Ticket"; if no other Ticket owns it, it is sent to Eval.

Two more details:

Subscription and "Ownership": Who Gets the Follow-up Message

This is the easiest part to get lost in, and it shows the design at its best.

A message a person sends in a Ticket's own Thread belongs to that Ticket's Executor; it does not go through Eval or produce a Decision. The Executor either handles it within ticket scope or hands it back: when the request is out of scope or belongs to another Ticket.

Only when no Ticket owns the message does it go into a fresh Eval, with candidates carrying each Executor's hand-back reason.

When a Ticket ends, it releases follow-up messages its Executor did not read or handle; those not confirmed, answered, or handed back each go to Eval.

Proactive and passive are also separated: an Executor can subscribe to related Threads (like another issue or PR) as context-only; messages there reach the Ticket but do not authorize anything and do not wake a finished Ticket.

Execution: How a Ticket Lives

docs/003-execution.md divides an open Ticket into mutually exclusive phases, taking the first match from the top:

Phase Condition Panel Label
person / delivery Delivery to Executor fails Input undelivered
person / answer There is an Attention (a question awaiting a human) Awaiting answer
person / review Latest report is ready Awaiting review
person / blocked, failed Latest report is blocked or failed, and no one has replied since Blocked · Failed
working / queued No Assignment, or waiting Queued
idle Report is waiting, or Assignment has ended Waiting for a Trigger
working Everything else Working

Any person phase means "cannot proceed without human input". A new human message puts a blocked or failed Ticket back into the Executor's hands.

What an Executor is: each Ticket gets an Executor Session named worker-<ticket id> and a directory named after the Ticket's short name. The Session runs commands under the operator's OS user identity without approval. Foreground shell commands exceeding 5 seconds are moved to background tasks, so the worker can receive new messages in the next step instead of waiting on a long command.

The document's rules for "background work" are detailed:

Concurrency: the configured concurrency cap applies to worker slots, with one extra slot reserved for human messages or status requests; new work does not crowd out the human continuing existing Tickets.

Preparing the directory: before the first Assignment, if the Ticket directory does not exist, a prep command runs under sh in the execution root, limited to 10 minutes; a typical use is git worktree to create a checkout. The final segment of the branch name matches the Ticket's short name, so the PR belongs to that Ticket.

Execution variables: the prep command and the Executor read the same variables, e.g. DSH_SUPERAGENT_DIR, DSH_SUPERAGENT_TICKET, DSH_SUPERAGENT_GITHUB_REPOSITORY, DSH_SUPERAGENT_GITHUB_ACCOUNT, with no credentials.

Merging: Governed by Prompts, Not the Host

Auto-merge is controlled by the "delivery requirements" prompt block; the host has no merge-related decision logic.

By default the Executor never enables auto-merge under the agent account, because GitHub attributes the merge to whoever enabled it. Delivery requirements must specify a different account's CLI to merge, otherwise a human merges.

The default instructions allow auto-merge only when all of the following hold: the PR was opened for this Ticket, is ready, required approvals cover the head commit, and total lines added/deleted are under 200. Before pushing a new version, the Executor withdraws auto-merge.

The document is level-headed: these instructions constrain the agent, not GitHub's merge rules. To enforce approvals, use branch protection and require stale approvals to expire.

Prompts: How the Team Shapes the Agent

docs/004-prompts.md spells out what the team can change:

Block Content
Communication When to message humans, how to write, the default opening line of each GitHub message (This is by an automated agent, not a human), how to handle reviews, which normal accounts are review bots
Ticket scope When a Ticket continues, when to stop with a draft
Delivery requirements Evidence in PRs, auto-merge conditions and line thresholds, commit author
Team skills Knowledge the agent loads when needed, e.g. an identities skill mapping Feishu users to GitHub accounts

The system prompt is assembled in a fixed order: shared instructions and role, the three team blocks, subscription and reply, scheduling or work instructions, admission, handoff, environment, and finally the Policy block. The Policy block regenerates on every model request and sits last, so policy changes do not modify earlier prompt text (cache-friendly).

Priority, strongest to weakest:

  1. Tool- and host-enforced facts (identity, permissions, argument checks, reply purpose, length limits); prompts cannot change these
  2. Built-in and generated blocks (including team overrides)
  3. Process and communication requirements in proactive Ticket match rules, effective only for that Ticket's Executor
  4. Team blocks and team skills
  5. External text: messages, comments, documents, quotes. It is data; it never changes rules or authorization

The last point is the line of defense against prompt injection: no matter how command-like outside text looks, it is only data.

Built-in text principles are also worth reading, for example:

Failure and Recovery

The execution document spends substantial space on "what to do when things break":

Panel: Answers Only Three Questions

docs/005-panel.md mandates that the panel answers three questions in order: Is there anything I need to handle now? Is the system healthy and doing the right thing? What is the history of one piece of work from Trigger to Eval to Ticket?

Tabs run along the workflow: Overview, Source, Trigger, Eval, Execution, Settings. Overview lists Tickets needing action first, then system issues, 24-hour activity counts, and Executor load.

Code Structure

A rough layering under src:

Directory Contents
src/core Domain core: engine.ts, evals.ts, tickets.ts, assignments.ts, intake.ts, replies.ts, ports.ts, etc.
src/sources GitHub and Feishu Source implementations: reading, triggering, channels, polling, registration
src/executor DSH integration (dsh.ts) and background task management (background.ts)
src/app Runtime, HTTP interface, settings, prompt assembly, session management, migrations, tools
src/client Panel frontend (React / TSX)
src/infra Commands, environment, health checks, paths
prompts/, skills/ Default prompts and GitHub, Feishu skills
tests/ Extensive tests; the largest files runtime.spec.ts ~142 KB, core-engine.spec.ts ~107 KB

docs/007-architecture.md is ~70 KB of architecture docs; docs/008-cookbook.md ~30 KB explains how to add a new Source. I did not read those two line-by-line this time.


Scope and Limitations


Project Address and Resources

Official Resources

Related Resources


Summary and Outlook

Key Takeaways

  1. Attention is a cost: every message, setting, and panel element must justify its cost to human attention, or be removed
  2. Proactive, but restrained: act only when asked or when team rules allow; proactive intake records only by default, does not execute
  3. Authorization is traceable and immutable: Mandates are immutable; only acceptance, human stop, and re-validation failure can change them; external text is always just data
  4. Who owns this message: subscription and "hand back" mechanisms ensure each follow-up message has exactly one owner, so it is neither double-processed nor abandoned
  5. The documentation itself is a product: numbered sequential reading, recording rejected options and reasons, makes a strong design-document template

Who It Is For

Suggestions

Do not install it first. Read docs/000-philosophy.md through docs/003-execution.md in order; the four together are not long. Then decide whether to run it on your own repo. If you do try it, use a dedicated GitHub account, whitelist only yourself, keep intake mode in observe, and let it "want to" work for a while before deciding whether to loosen anything.


Explore PrimeSkills - a selection of AI agents and skill tools, each verified against real workflows. No hype, only genuinely useful tools.

Visit my homepage for more insights and interesting products.