Files
deepseek-harness/docs/rfc/implemented/architecture/2026-06-11-microkernel-event-taxonomy.md
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

1.9 KiB

RFC: Microkernel — extension via Cordis event taxonomy, one concrete loop

Status: implemented

Problem

The product principle is "everything is a plugin": hooks, /goal, /loop, dynamic workflows, compaction, sandboxing, permissions, UI, persistence, MCP, skills must all be writable as plugins without modifying the core.

Decision

Pure Cordis event taxonomy. The loop's extension seams are typed events with deliberate dispatch modes:

  • waterfall (around-middleware) where plugins mutate or veto: agent/prompt-submit, agent/request, agent/step-result, agent/turn-continuation, tools/pre-execute, tools/post-execute, llm/stream, system-prompt/assemble.
  • emit (sync fire-and-forget) for notifications: turn/step boundaries, stream chunks, lifecycle, errors.
  • parallel (awaited) for the one durability checkpoint: session/flush.

The event vocabulary lives in interface packages (dsh-agent declares the agent/* events); @deepseek-ai/dsh-agent-loop is the only concrete loop plugin and is itself swappable — nothing outside it may depend on it.

Alternatives considered

A purpose-built middleware stack (koa-compose style) and an explicit phase state machine plugins insert into — both would re-implement dispatch, disposal, and reload semantics that Cordis's native event system already provides; as Cordis effects, listeners get HMR and disposal for free.

Consequences

  • Every MVP feature maps to a listener (the feature → mechanism map is the proof obligation, kept current).
  • HMR and disposal come free: listeners and registrations are Cordis effects.
  • Waterfall semantics (call next() or short-circuit) are non-obvious and must be taught — documented in AGENTS.md and covered by composition tests.
  • The loop must be defensive: plugin exceptions are contained at turn level, steering from any seam is never stranded (regression-tested).