What an Attention Budget Buys: Inside DeepSeek’s dsh-superagent-prototype

DeepSeek’s MIT-licensed TypeScript prototype is built around a single accounting unit — the human attention each message, setting and paragraph of documentation costs — and its nine numbered design documents show precisely what that accounting buys an agent team (docs/000-philosophy.md).

Framing: attention budget is my term, not DeepSeek’s

This case study uses the term “attention budget” as its own framing device; it is not DeepSeek’s wording, and the phrase does not appear in the philosophy document the repo actually ships (docs/000-philosophy.md). What the repository says instead is: “Take as little human attention as possible, and give as much value as possible.” (docs/000-philosophy.md) and “Every part of the project is judged by the attention it costs.” (docs/000-philosophy.md)

By attention budget I mean the finite quantity of a person’s notice an agent system may spend on itself — messages, notifications, questions, settings, panel elements — before it becomes a net cost rather than a net gain. The repo derives these behavioural consequences for the agent from that accounting (docs/000-philosophy.md):

The design-side equivalents are equally short: “Few concepts.” · “Few settings.” · “A panel that shows only what needs a person.” · “Documents read in order.” (docs/000-philosophy.md) The closing line of the document is the acceptance test: “The goal is the right help at the right time, and nothing at any other time.” (docs/000-philosophy.md)

Provenance: what was measured, not what was claimed

Everything in this section and the next is first-party: repo metadata from the GitHub API and file counts from a clone we measured ourselves on 2026-11-02 (GitHub API).

Field Value
Licence MIT
Language TypeScript
Stars / forks (census 2026-11-02) 11,196 / 1,138
Created 2026-10-31
Last push 2026-10-31
Analysed commit 6337fc823ce20251c8de8085948165c81aaa701e
Repository deepseek-ai/dsh-superagent-prototype

The star count moved fast: the explainx.ai summary reported “about 5,400 stars” on or around 2026-11-01, before our 11,196 reading the next day (explainx.ai summary). The same summary is also the source for calling this bundle a research prototype — that phrase is the secondary source’s characterisation of the design article, not README wording (explainx.ai summary).

Our census of the working tree

Measured at the commit above, our own counts (GitHub API):

Measure Value
TypeScript files (excluding .git) 147 .ts + 30 .tsx
Source files under src/ 110 files, 15,205 lines
Test files under tests/ 65 files, 14,960 lines
Test cases / describe blocks 794 / 72
Numbered docs 9 files, 000–008
Decision reason codes in src/core/reasons.ts 20

Test lines land at roughly 0.98× source lines, and the 794 test cases sit across 65 test files — a ratio worth stealing before you steal any architecture (docs/007-architecture.md).

Authorization: three strengths, one admission table

The authorization document defines exactly three strength values (docs/002-authorization.md):

  • explicit — “A person on the list addresses the agent, or follows up on a Thread that already has a Ticket; a cell of the admission table set to explicit request”
  • inferred — “A person not on the list follows up on a Thread with a Ticket, unless their cell of the admission table is explicit; a cell of the admission table set to inferred candidate; a message of a bot on the Source’s bot list that addresses the agent or arrives where the Source receives every message”
  • not admitted — “Any other bot’s message, everything the admission table ignores, and every inferred case while the accept mode is off”

The admission table has three rows, each with a choice set and a default (docs/002-authorization.md):

Cell Choices Default
On the list, not addressing the agent inferred, ignore inferred
Not on the list, addressing the agent explicit, inferred, ignore ignore
Not on the list, not addressing the agent inferred, ignore ignore

Accept modes decide what happens to an inferred candidate (docs/002-authorization.md):

Mode Effect
off “Nothing inferred becomes a candidate…”
observe (default) “Inferred candidates are assessed; a positive assessment is recorded as ignore marked "would accept", and nothing is accepted”
auto “A positive assessment of an inferred candidate accepts it”

Explicit requests work in every mode, and the rollout advice is literal: “Start in observe and switch to auto after reviewing the recorded Decisions.” (docs/002-authorization.md) A proactive accept requires at least one matching rule, and each assessment judges every enabled rule exactly once (docs/002-authorization.md).

The Mandate lifecycle

An accept grants a Mandate: “the Policy version, the scope, the strength, the matched rules, the sender’s identity on that Source and how the Source received the Trigger.” (docs/002-authorization.md) It is then governed by four rules from the domain document (docs/001-domain.md):

  1. The Mandate is immutable; wider scope means a new Ticket.
  2. A Ticket’s end does not end the Mandate.
  3. Only a person’s stop withdraws it, and a Policy that no longer holds it revokes it.
  4. It is revalidated against the current Policy before an ended Ticket resumes.

A Policy that weakens therefore does not immediately stop open Tickets accepted under it; it can revoke their Mandates when they are revalidated before resuming (docs/001-domain.md). The same document carries a rejected-concepts table whose refusals are as instructive as its features — it rejects “Principal or Membership as an entity, or mapping identities across Sources”, it rejects “An "append to Ticket" Decision”, and it rejects “Cancelling running Tickets on a Policy change” (docs/001-domain.md).

Execution: seven stages and the numbers that bound them

Tickets move through seven stages, first match wins, labels verbatim (docs/003-execution.md):

Stage Label
person / delivery Input undelivered
person / answer Awaiting answer
person / review Awaiting review
person / blocked, failed Blocked · Failed
working / queued Queued
idle Waiting for a Trigger
working Working

The hard numbers that keep a worker from eating the whole day (docs/003-execution.md):

Control Value
Human slack in the queue One extra slot beyond the configured concurrency limit, for a person’s message or a status request
Background cap At most 30 minutes after each turn; shell jobs are killed and the Ticket is reported waiting; subagents are allowed to continue
Shell → background 5 seconds under dsh-superagent-worker and dsh-superagent-router; 60 seconds under standard
Auto-merge default PR ready, required approvals cover the head commit, additions plus deletions fewer than 200 lines
Pass cadence One pass every two seconds and whenever a command asks
Delivery retry Retried after 2 seconds, then a delay that doubles up to a minute
Prepare command Runs once with sh in the execution root; ten minutes to finish
Shutdown wait Waits up to 10 seconds for each worker’s background work; a process restart ends that work outright

The document is candid about what these are: “These wrappers and directories establish defaults, not a security boundary. A worker can still execute a program by absolute path.” (docs/003-execution.md) Treat every number above as a default you inherit, not a wall you rely on (docs/003-execution.md).

Architecture: one writer, five parts, one direction

Part Module Responsibility
Runtime src/app/runtime.ts “the composition root; it contains no domain rules”
Engine src/core/engine.ts “the only writer of Triggers, Threads, Decisions, Tickets and Assignments”
Intake EnginePart Trigger storage, fan-out, queue for Eval (depends on Tickets)
Evals EnginePart Batching, gate strength, deadline, requeue; ends each Eval with a Decision: accept, stop, ignore or unavailable
Tickets EnginePart Lifecycle, Mandate, Subscriptions, resume/retry/restart/stop/end (depends on Replies)
Assignments EnginePart Executor and worker reports (depends on Tickets, Replies)
Replies EnginePart Channel writes through the Outbox; depends on nothing

Dependencies between the parts flow in one direction, and the ports that bound the core live in src/core/ports.ts: Repositories, a current-Policy getter, SourceScope, Assessor, Executor, Outbox, plus optional prepareTicket, now and emit (docs/007-architecture.md). The naming convention is a small thing that pays rent: “Commands use imperative names such as stopTicket; facts reported by adapters use past-tense names such as assignmentStarted.” (docs/007-architecture.md)

Secondary reporting: what the launch article claims

Everything in this section is SECONDARY. It comes from the explainx.ai summary of a DeepSeek article published on X on 2026-11-01 (X article pointer); we could not fetch the article itself because of a bot wall, so none of it is repo behaviour and none of it is first-party measurement (explainx.ai summary).

The four-design ablation runs five times each, with the authors’ own caveat attached: “the results below are indicative only.” (explainx.ai summary)

Design Task time p50 / p95 (min) Cache-read tokens per run
Super-agent 12.4 / 15.7 23.2M
Super-agent without pass-through 12.6 / 15.5 31.8M
Single session + subagent tool, neutral prompt 20.4 / 29.5 6.1M
Single session + subagent tool, delegation-first prompt 13.8 / 29.0 10.8M

Run conditions, verbatim: “Each run had about 300 messages from a group chat and GitHub CI, of which about 20 were work requests. The rest were chat, follow-ups, cancellations and CI noise. Coding was simulated by a tool that only uses time, so the test measures scheduling, not coding skill.” (explainx.ai summary)

The three findings: prompts are not a reliable delegation switch — the neutral prompt produced no subagent call in any of 5 runs while the delegation-first prompt delegated in 4 of 5; you pay in tokens, with the super-agent using about 2 to 4 times the cache-read tokens of the single-session designs; and pass-through saves tokens, not time, with about 30% more decisions and about 37% more tokens but unchanged task times without it (explainx.ai summary).

Router batching under load, same secondary source: trigger rate rising from about 1 to about 40 per minute, average batch size from 1.0 to 2.8, time per request from 2.5 s to 3.9 s, and amortised time per decision falling from 6.4 s to 1.6 s (explainx.ai summary). Per-channel reply rules are also secondary (explainx summary, channel-rules table): IM and group chat get light, interruption-free replies with a hard cap of 100 words per reply, while GitHub, email and docs get structured, dense output (explainx.ai summary).

Where the prototype and the article diverge

Article claim (SECONDARY) Repo reality (first-party)
Watchdog module (§6) No Watchdog module exists in the part table; the closest analogues are the 30-minute background kill, restart handling and blocked/failed stages, which are not the same thing (docs/007-architecture.md)
Full-duplex start()/stop() (§4) No full-duplex lifecycle appears anywhere in the architecture doc (docs/007-architecture.md)
Model tiering: lighter router, most capable workers Absent; the repo fixes tool presets (dsh-superagent-worker, dsh-superagent-router, standard), not models (docs/003-execution.md)
Inline / Spill / Chain of Recall context strategy Not in the repo’s concept table, which lists Source, Thread, Eval, Mandate, Subscription, Correlation, Channel, Policy, Ticket, Assignment, Trigger (docs/001-domain.md)
“Two-stage filter” (fast path code / slow path LLM) The repo says the Eval runs “in two layers: gate and assessment” — the same shape, but the repo’s names are gate and assessment (docs/002-authorization.md)
Workers “resolve conflicts themselves” via shared PR event streams Qualified in the repo: Subscription fan-out grants no authority, and Executors hand a message back once when work exceeds Ticket scope (docs/001-domain.md)
Security: “a server-side intrusion or a prompt injection compromises the Agent Loop, every endpoint device connected to it could be taken over” The repo’s own line is that wrappers and directories “establish defaults, not a security boundary” (docs/003-execution.md)

One tension stays open. The article summary says the Router “can run without a Bash tool at all” (explainx.ai summary), while the execution doc describes a main Session using dsh-superagent-router “with the same 5-second shell and job-wait limits and a smaller tool set for routing” (docs/003-execution.md). Both cannot be the whole story; treat it as unresolved.

Copy this into your own harness

  1. Observe before you auto-accept. Default to observe, record would-accept Decisions, then switch to auto after review — the repo’s own rollout advice (docs/002-authorization.md).
  2. Ignore strangers by default. The admission table defaults to ignore for anyone not on the list who is not addressing the agent (docs/002-authorization.md).
  3. Reserve a slot for humans. Keep one slot beyond your configured concurrency limit for a person’s message or a status request (docs/003-execution.md).
  4. Cap background work and report the wait. Kill shell jobs at 30 minutes, report the Ticket as waiting, let subagents finish (docs/003-execution.md).
  5. Gate merges on size. Auto-merge only a ready PR whose approvals cover the head commit and whose additions plus deletions total fewer than 200 lines (docs/003-execution.md).
  6. Run a two-second heartbeat. One pass at a time, every two seconds, plus on demand (docs/003-execution.md).
  7. Split composition from domain. Keep the Runtime a composition root with no domain rules, and make the Engine the single writer of domain state (docs/007-architecture.md).
  8. Enforce imperative commands and past-tense facts across your event names, and ask one concrete question at a time (docs/007-architecture.md).

FAQ

Is this production-ready? No source supports that. The explainx summary describes the originating article as discussing architectural ideas rather than existing product features, and the repo’s own execution doc says its wrappers “establish defaults, not a security boundary” (explainx.ai summary) (docs/003-execution.md).

Is “attention budget” DeepSeek’s term? No. It is this case study’s framing term. The repo’s phrasing is “Take as little human attention as possible, and give as much value as possible.” (docs/000-philosophy.md)

Are the benchmark numbers first-party? No. The ablation, batching and 100-word cap are SECONDARY reporting of the explainx.ai summary of an X article we could not fetch (explainx.ai summary) (X article pointer).

What is missing versus the article? No Watchdog module, no full-duplex start()/stop(), no model tiering, no Inline/Spill/Chain of Recall, and a qualified account of worker-to-worker PR-conflict handling (docs/007-architecture.md).

What licence applies if I reuse the patterns? MIT, per the GitHub API census of the repository (GitHub API).

The Bottom Line

The prototype’s real contribution is not a novel agent loop; it is a disciplined answer to who may wake the agent, how long it may run unattended, and how little it is allowed to say. Authorization defaults to silence, execution defaults to a deadline, and the architecture defaults to a single writer — three decisions that cost almost nothing to copy and buy back most of a person’s attention. The launch article is a design essay with numbers we could not verify at the source, and the gaps between it and the code are wide enough that you should read the nine docs, not the summary (docs/000-philosophy.md).

How This Guide Was Built

The repo was cloned and measured at commit 6337fc823ce20251c8de8085948165c81aaa701e on 2026-11-02. The nine numbered documents, 000 through 008, were read first-party, including 000-philosophy, 001-domain, 002-authorization, 003-execution and 007-architecture. Star and fork figures come from a measured GitHub API census (GitHub API). Every benchmark, ablation, batching and reply-cap number in this article is SECONDARY reporting of an explainx.ai summary of a DeepSeek X article that could not be fetched because of a bot wall; the X URL is cited as a pointer only. The deployment document — machine limits in the plugin configuration and a one-minute default poll interval for new Issues and comments — was read directly: docs/006-deployment.md.

  • ToolBrain — tool reviews, LLM comparisons, and AI workflow guides
  • CodeIntel Log — code quality, debugging, and software engineering benchmarks

Cross-links automatically generated from NiteAgent.

← Back to all posts