deepseek-harness/packages/core
Tianyi Cui abe80cec68 fix(loop): record a durable prompt/blocked for every vetoed prompt
Address review on the interception-seams PR: PromptDecision.reason is
documented as the durable record of why a prompt was blocked, but the loop
only surfaced it via the fully-blocked batch's `rejected` turn/end. In a MIXED
batch — one queued prompt blocked, another allowed — the turn does not end
`rejected`, so the blocked prompt and its reason vanished from the session log
entirely.

Add a `prompt/blocked` SessionEventMap variant (content + source + reason),
appended in the open turn at the veto point in place of the user/message the
prompt would have become. It is a non-surface, turn-enclosed event (like
todo/write): it never reaches deriveMessages(). The fully-blocked batch still
also ends `rejected` for boundary balance + ACP settlement. Regression test
drives a mixed batch and asserts the blocked prompt is recorded while the
allowed one runs — proven red without the append.
2026-07-02 17:03:53 +08:00
..
agent fix(loop): record a durable prompt/blocked for every vetoed prompt 2026-07-02 17:03:53 +08:00
agent-core fix(events): address Codex review — protect post-execute result, purge stale tools/execute refs 2026-06-30 20:25:30 +08:00
agent-loop fix(loop): record a durable prompt/blocked for every vetoed prompt 2026-07-02 17:03:53 +08:00
session fix(loop): record a durable prompt/blocked for every vetoed prompt 2026-07-02 17:03:53 +08:00
system-prompt docs(compact): align seam docs with the pre-step seam and record session/invariants changes (CBR-003) 2026-06-26 13:51:45 +08:00
tools fix(events): address review — core.md turn-only taxonomy, RFC mechanism names, post-execute content snapshot 2026-07-01 15:39:08 +08:00
README.md Merge remote-tracking branch 'origin/worktree-hooks-b-bash-seam' into worktree-hooks-c-interception 2026-07-01 15:37:54 +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.