# Conflicts: # AGENTS.md # docs/config-catalog.md # docs/cordis-catalog/events.md # docs/cordis-catalog/services.md # docs/core-data-structures/core.md # docs/event-producer-consumer.md # docs/persistence-catalog.md # docs/rfc/implemented/architecture/2026-07-05-reconstructable-requests.md # docs/rfc/implemented/feature/2026-06-15-code-mode.md # docs/rfc/implemented/feature/2026-06-30-hook-bridges.md # docs/rfc/implemented/feature/2026-06-30-interception-seams.md # docs/rfc/implemented/feature/2026-07-08-repeat-tool-guard.md # docs/rfc/proposed/simplification/2026-07-04-prune-dead-core-spine-surface.md # examples/AGENTS.md # examples/acp-agent/cordis.yml # examples/acp-agent/tests/acp.snapshot.ts # examples/echo-agent/cordis.yml # examples/sandbox-acp-agent/cordis.yml # packages/cordis/tool-cordis/src/api-catalog.ts # packages/core/agent-core/README.md # packages/core/agent-core/src/index.ts # packages/core/agent-loop/README.md # packages/core/agent-loop/src/loop.ts # packages/core/agent-loop/tests/interception.spec.ts # packages/core/agent/src/types.ts # packages/core/tools/README.md # packages/core/tools/src/code-mode.ts # packages/core/tools/src/index.ts # packages/fs/fs-local/src/index.ts # packages/fs/fs/README.md # packages/fs/fs/src/index.ts # packages/guard/repeat-tool-guard/README.md # packages/guard/repeat-tool-guard/src/index.ts # packages/hooks/hooks-claude/src/index.ts # packages/hooks/hooks-codex/src/index.ts # packages/ui/acp-agent/src/index.ts
@deepseek-ai/dsh-tool-cordis
The self-referential cordis toolset: three model-facing tools over the live runtime the agent runs inside. Design home — sandbox semantics, mount lifecycle, cross-mount composition, the generated API catalog, standing decisions: the toolset RFC.
What it does
cordis_inspect— read-only report over the runtime: services, the loaded-plugin list, registered tools, the dynamic-mount table, and the catalog-backedapi/eventsreferences.cordis_mount— evaluates model-written JavaScript (the body of an async function) in anode:vmsandbox; the code mustreturna cordis plugin, which is mounted under thecordis-dynamicgroup fiber and tracked asdyn-<n>.cordis_unmount— disposes one mount by id, returning only after quiescence.
Exact model-facing schemas: the generated tool catalog.
Trust stance
The sandbox isolates globals but is not a security boundary. Node globals are absent or redirect to Cordis services such as ctx.fs, ctx.web, and ctx.bash, and writes to globalThis stay local, but host-realm helpers make escape possible. Mounted plugins receive a façade without framework internals, yet its allowed services affect the live runtime. Treat this toolset like bash access; see the design and trust stance.
Config
| Field | Default | Meaning |
|---|---|---|
vmTimeoutMs |
5000 |
Bound on the SYNCHRONOUS portion of mount-code evaluation; an async body escapes it |
The generated API catalog
src/api-catalog.ts is generated by scripts/gen-cordis-api.ts from the same AST walk as docs/cordis-catalog and freshness-gated by pnpm run verify-cordis-api (in doc-sync) — never edit it by hand. cordis_inspect intersects it with the live service store at call time.
Rendering
All three tools render generic cards (read / execute / delete); cordis_mount carries the mount code as rawInput. Presenters are pure functions of the args; results keep the default text rendering.
Export shape
Namespace plugin: named exports name / inject / Config / apply, no default export (docs/postmortem/0001).
Model Experience
Tool schemas
What the model sees: The conversation model sees the generated cordis_inspect, cordis_mount, and cordis_unmount schemas whenever this plugin is visible.
Token effect: Fixed schema cost on every request in that tool view.
Tool-call history and results
What the model sees: Inspect joins selected sections exactly as ## <section> then a newline and the data-dependent body, with one blank line between sections. Mount returns mounted <id> (plugin "<name>", state: <state>), optionally inserting — waiting for service(s): <names> (activates when provided) before the closing parenthesis. Unmount returns unmounted <id> (plugin "<name>"); an unknown id becomes Error: no dynamic plugin with id "<id>" (list mounts with cordis_inspect what:"dynamic"). The submitted mount program remains in the assistant tool-call history.
Token effect: Inspect output and mount code are data-dependent and resent until compaction; lifecycle acknowledgements are small.
Later requests after a mount
What the model sees: A mounted plugin may register tools, prompt contributions, or listeners that change later requests for the scopes it targets; unmount removes those contributions after quiescence.
Token effect: Indirect token impact equals the mounted plugin's contributions and lasts only for the mount lifetime.
Known Limitations and Deferred Work
- The sandbox is containment for honest code, not a security boundary — host-realm helpers on the sandbox global are reachable, so mount code can reach Node; load this plugin as deliberately as you would grant a bash tool (see § Trust stance).
- The
ctxfaçade exposes noeffect()— mount code cannot register a bespoke disposer;on/provide/tools.registercover every mount seen so far, and a guardedeffectwaits on a real need (FIXME(sandbox-effect)). vmTimeoutMsbounds only synchronous evaluation — an async mount body escapes it; there is no async budget on mount code.