Files
deepseek-harness/packages
Tianyi Cui e6fad266a6 docs(rfc): define and enforce a uniform RFC format; adopt it across the corpus
Define the in-file RFC contract in docs/rfc/README.md § The file format:
the header block (`# RFC: <title>` plus a dateless Status enum
cross-checked against the lifecycle folder), the per-lifecycle body
skeleton (a Problem opener everywhere; Proposal/Alternatives considered/
Acceptance criteria/Risks in proposed/; present-tense Decision/
Consequences with proposal-era headings banned in implemented/; the
frozen proposal shape in rejected/), and a mandatory Alternatives
considered section with a date-fenced grandfather comment for pre-format
RFCs whose alternatives are not reconstructible from the record.

Enforce it with a new doc-sync gate, scripts/verify-rfc-format.ts, and
normalize all 112 RFCs to it: ~15 Status-line spellings collapse to the
enum, 29 Context openers become Problem, the 39 legacy-format XXX debt
markers are resolved and banned from reappearing, proposal-era sections
in implemented RFCs are rewritten to shipped reality (including the
web/fs/subagent seam RFCs' migration plans and test checklists, closing
the doc-tiers deferred-work item on the web seam), every RFC gains an
Alternatives considered section or the grandfather comment, and the
bilingual pair is re-mirrored and re-recorded.

Move the generated index tables out of README.md into a fully generated
docs/rfc/INDEX.md — gen-rfc-index now writes the whole file, and
verify-rfc-classification checks its freshness and rejects index-shaped
rows in the curated README — which makes room for the format contract to
live in the README front door instead of a separate FORMAT.md.

The decision record, and the first RFC written in the new format, is
docs/rfc/implemented/process/2026-07-05-uniform-rfc-format.md.
2026-07-05 22:58:25 +08:00
..
2026-07-05 15:31:50 +08:00
2026-07-05 00:45:39 +08:00
2026-07-05 15:31:50 +08:00
2026-07-05 15:31:50 +08:00

Packages

Harness packages, all under the @deepseek-ai/dsh-* scope. Each package is a Cordis plugin (microkernel-style): it exports either a default Service subclass or a functional plugin, declares its ctx key/events through declaration merging, and exposes extension points through ctx.effect(), ctx.on(), and ctx.waterfall(). Authoring conventions: AGENTS.md (subtree) and the root AGENTS.md § Conventions.

Hierarchy

Packages are grouped by modular role at packages/<group>/<pkg>/. The group directory is a pure container (no package.json of its own); the package name stays @deepseek-ai/dsh-<pkg> regardless of group. Each group README is the canonical per-package map — package roles, ctx keys, and the product-vs-support split live there, next to the code.

Group Role Release expectation
core/ Product API spine: session, system-prompt, tools, agent, and the concrete loop Product — stable surface
llm/ LLM capability family: the abstract service + provider adapters Product — stable surface
bash/ Bash capability family: the executor seam, a local impl, and the model-facing tool Product — stable surface
fs/ Filesystem capability family: the abstract seam, a local impl, and the model-facing file tools Product — stable surface
compact/ Compaction capability family: the abstract seam + a basic backend (tool deferred) Product — stable surface
subagent/ Subagent capability family: the provider-registry seam and the model-facing delegation tool Product — stable surface
web/ Web capability family: the abstract seam, search/fetch provider impls, and the model-facing web tools Product — stable surface
todo/ Todo/planning family: the model-facing todo_write tool (whole-list task tracking on the session log) Product — stable surface
hooks/ Hook bridges + the shared Claude Code / Codex wire-protocol library Product — stable surface
session-persistence/ Persistence capability family: the seam + JSONL/SQLite backends Product — stable surface
ui/ Editor/client integration surfaces (the ACP bridge) + the app packages Product — stable surface
support/ Dev/test/example infrastructure (invariants, replay adapter, subagent mock) Support — lower compatibility expectations
util/ Low-level zero-dependency utilities shared across groups (the Branded<B> primitive) Support — small, stable, harness-dep-free

The split is the point: a package's group says whether it is part of the product API or support/test/example infrastructure, so release and removal decisions do not treat every package as an equal public contract. New packages join an existing group; adding a new top-level group is a deliberate act (extend the group READMEs and this table).

Dependencies

The inter-package dependency graph is generated: docs/module-graph.md (pnpm run gen-module-graph, freshness-gated in CI).

The rule it must obey: extension plugins depend on interfaces, never on the concrete loop. dsh-agent-loop is swappable — UI/hook/tool plugins keep working against the dsh-agent vocabulary if the loop is replaced. The sanctioned exception is a composition/bundle package like dsh-agent-core, whose whole job is to assemble the concrete spine: it depends on dsh-agent-loop (and the other concrete spine plugins) on purpose. The rule constrains plugins that EXTEND the system, not the bundle that COMPOSES it — swapping the loop means shipping a different bundle, not rewiring every extension. A swappable capability splits into interface / implementation / consumer packages (the bash trio is the template — see capability seams).

Each package has its own README.md with purpose, service API, events, extension points, and deliberate non-goals (TODOs).