Files
deepseek-harness/packages/core
Tianyi Cui c6d2eeea6b refactor(events): remove the agent/steering mirror emit
agent/steering was the last transient mirror of a durable session event:
drainSteering appended the durable steering/message {turn, content, source}
and emitted the identical fact one line later. Zero production listeners
existed — every steering consumer (hook bridges, goldens, deriveMessages)
reads the durable event — and the one regression test subscriber asserted
a fact the log already records.

Remove the declaration (dsh-agent types + JSDoc list + README row), the
emit in drainSteering (its ctx parameter goes too), and the emit line in
the loop-pseudocode blocks (loop.ts module doc, architecture.md); the
cordis catalog is regenerated. The regression test now pins source
preservation on the durable steering/message event. Live-notification
needs keep their surviving homes: agent/queued at enqueue time,
session/event at drain time.

RFC: docs/rfc/implemented/simplification/2026-07-04-remove-agent-steering-mirror.md
(moved from proposed/, amended to shipped reality). The three implemented
RFCs that stated the retention — the boundary-mirror removal, the
stream-chunk removal, and event-domain-semantics — are amended to point
at that RFC as the record of the removal, per implemented/AGENTS.md.
The rejected retire-mid-turn-steering RFC keeps its frozen text (it
records the declined proposal); the steering capability itself —
steer(), the durable event, continuation forcing — is untouched.
2026-07-04 15:36:40 +08:00
..

core/ — product API spine

The packages every harness build is assembled from: the session log, the system-prompt assembly, the tool registry, the agent vocabulary, and the one concrete loop that drives them. These are product packages — the stable surface plugins and consumers build against.

Package Role ctx key
session/ Event-sourced session log + in-memory store ctx.sessions
system-prompt/ Prompt-section + tool-schema assembly registry ctx.systemPrompt
tools/ Tool registry + tools/pre-execute/tools/post-execute pipeline ctx.tools
agent/ Agent interface, registry, agent/* event vocabulary ctx.agents
agent-loop/ The concrete loop plugin: ReactLoopAgent + the loop driver ctx.agentLoop
agent-core/ Bundle plugin: the providerless/executor-less/UI-less spine as code (loads the spine)

agent-loop is the one concrete implementation of the agent seam and lives here because it is the harness's default product loop; everything else in core/ is interface/vocabulary. Plugins depend on the agent vocabulary, never on agent-loop directly, so the loop stays swappable.

agent-core is the composition counterpart: one bundle plugin that loads the whole providerless spine (timer + llm + sessions + system-prompt + tools + agents + invariants + tool-bash + agent-loop) and forwards agent-loop's agents list as its own config. App packages (ui/stdio-agent, ui/acp-agent) consume it and add only a front door; a leaf adds the swappable backends plus any optional product tools it wants to expose. It lives in core/ because it composes exclusively core/ + interface packages and ships no provider, executor, or UI of its own.