docs: document package KV cache effects
This commit is contained in:
@@ -2,5 +2,5 @@
|
||||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write
|
||||
adding-a-package.md: 2930cee9ab64b382f6211335ae639bce45629d1d
|
||||
adding-a-package.zh.md: 10e906c320203c3658c103fc8936540f72697d65
|
||||
adding-a-package.md: 2e4374caff589199288e67bbca58604231a17966
|
||||
adding-a-package.zh.md: 35b5b9a0705dd0b752d68093769a65c339f6b4e3
|
||||
@@ -16,7 +16,7 @@ packages/<group>/<pkg>/
|
||||
src/index.ts # service default export or plugin (name/inject/apply/Config)
|
||||
tests/<x>.spec.ts
|
||||
README.md # service API, events, extension points, design notes,
|
||||
# + gated Model Experience context blocks or short sentence
|
||||
# + gated Model Experience context blocks or short form
|
||||
# + the gated "Known Limitations and Deferred Work" section
|
||||
# (or a whitelist entry in scripts/verify-package-readme-limitations.ts)
|
||||
```
|
||||
@@ -55,6 +55,8 @@ Keep package-specific service API, config, events, extension points, and design
|
||||
|
||||
**Token effect**: Fixed, conditional, retained, replaced, capped, or zero-direct token effect.
|
||||
|
||||
**KV Cache effect**: Append-only, prefix-stable, replacing, or independent behavior, including the exact conditions that may invalidate reuse.
|
||||
|
||||
#### Verbatim text for this context surface, when needed
|
||||
|
||||
```markdown
|
||||
@@ -66,9 +68,9 @@ Stable system-prompt prose of any length, or another long non-generated literal,
|
||||
- **Consumer-visible gap** — exact boundary, consequence, or maintainer constraint.
|
||||
````
|
||||
|
||||
Fill Model Experience from the implementation. Use one H3 per direct, conditional, capped, lifetime, or auxiliary-model surface, with the two fields shown above. Quote stable text owned by the package: system-prompt prose goes in a titled H4 plus `markdown` fence, other short literals stay inline with named placeholders, and other long literals use the same nested form. Summarize only data-dependent or provider-owned text. A tool-schema surface links its anchored section in the generated [tool catalog](../tool-catalog.md) and states only deltas absent there. Keep prompt and schema surfaces separate when scoping can hide one without the other. The [prose standard](../../.agents/skills/dsh-prose-standard/SKILL.md) governs completeness and ownership; the verifier enforces the mechanical shape.
|
||||
Fill Model Experience from the implementation. Use one H3 per direct, conditional, capped, lifetime, or auxiliary-model surface, with the three fields shown above. Quote stable text owned by the package: system-prompt prose goes in a titled H4 plus `markdown` fence, other short literals stay inline with named placeholders, and other long literals use the same nested form. Summarize only data-dependent or provider-owned text. A tool-schema surface links its anchored section in the generated [tool catalog](../tool-catalog.md) and states only deltas absent there. Keep prompt and schema surfaces separate when scoping can hide one without the other. In `KV Cache effect`, distinguish append-only growth, a stable repeated prefix, replacement of earlier request tokens, and an independent model request, then name the package-owned changes that can invalidate reuse. “Does not invalidate” means the package preserves an already-reusable prefix; provider cache availability and eviction remain outside the package contract. The [prose standard](../../.agents/skills/dsh-prose-standard/SKILL.md) governs completeness and ownership; the verifier enforces the mechanical shape.
|
||||
|
||||
A package with no context effect or one consumer-owned path uses the audited `None, as ` or `Indirectly, through ` sentence in [`SENTENCE_MODEL_EXPERIENCE`](../../scripts/verify-package-readme-model-experience.ts); a model-agnostic generic package may instead join `NO_MODEL_EXPERIENCE_SECTION`. Do not expand either case into a description of another package's work. The limitations [allowlist](../../scripts/verify-package-readme-limitations.ts) is independent. The [Model Experience RFC](../rfc/implemented/process/2026-07-12-package-model-experience-contract.md) records the rationale.
|
||||
A package with no context effect or one consumer-owned path uses the audited `None, as ` or `Indirectly, through ` sentence in [`SENTENCE_MODEL_EXPERIENCE`](../../scripts/verify-package-readme-model-experience.ts), followed by a non-empty `**KV Cache effect**` field; a model-agnostic generic package may instead join `NO_MODEL_EXPERIENCE_SECTION`. Do not expand either case into a description of another package's work. The limitations [allowlist](../../scripts/verify-package-readme-limitations.ts) is independent. The [Model Experience RFC](../rfc/implemented/process/2026-07-12-package-model-experience-contract.md) records the rationale.
|
||||
|
||||
## 5. Verify
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ packages/<group>/<pkg>/
|
||||
src/index.ts # service default export or plugin (name/inject/apply/Config)
|
||||
tests/<x>.spec.ts
|
||||
README.md # service API, events, extension points, design notes,
|
||||
# + gated Model Experience context blocks or short sentence
|
||||
# + gated Model Experience context blocks or short form
|
||||
# + the gated "Known Limitations and Deferred Work" section
|
||||
# (or a whitelist entry in scripts/verify-package-readme-limitations.ts)
|
||||
```
|
||||
@@ -55,6 +55,8 @@ package.json 不变式(由 `pnpm run constraints` / `scripts/check-workspace-c
|
||||
|
||||
**Token effect**: Fixed, conditional, retained, replaced, capped, or zero-direct token effect.
|
||||
|
||||
**KV Cache effect**: Append-only, prefix-stable, replacing, or independent behavior, including the exact conditions that may invalidate reuse.
|
||||
|
||||
#### Verbatim text for this context surface, when needed
|
||||
|
||||
```markdown
|
||||
@@ -66,9 +68,9 @@ Stable system-prompt prose of any length, or another long non-generated literal,
|
||||
- **Consumer-visible gap** — exact boundary, consequence, or maintainer constraint.
|
||||
````
|
||||
|
||||
根据实现填写 Model Experience。每个直接、条件、上限、生命周期或辅助模型的 surface 使用一个 H3,包含上述两个字段。引用包拥有的稳定文本:系统提示词放在带标题的 H4 加 `markdown` 围栏中,其他短文本以命名占位符内联,其他长文本使用相同的嵌套形式。仅概述数据依赖或提供方拥有的文本。tool-schema surface 链接到生成的[工具目录](../tool-catalog.md)中对应的锚定章节,仅说明该处缺失的差异。当作用域可以隐藏 prompt 或 schema 其中之一而不影响另一个时,将二者分开。[行文标准](../../.agents/skills/dsh-prose-standard/SKILL.md)约束完整性与归属;验证器强制执行机械形状。
|
||||
根据实现填写 Model Experience。每个直接、条件、上限、生命周期或辅助模型的 surface 使用一个 H3,包含上述三个字段。引用包拥有的稳定文本:系统提示词放在带标题的 H4 加 `markdown` 围栏中,其他短文本以命名占位符内联,其他长文本使用相同的嵌套形式。仅概述数据依赖或提供方拥有的文本。tool-schema surface 链接到生成的[工具目录](../tool-catalog.md)中对应的锚定章节,仅说明该处缺失的差异。当作用域可以隐藏 prompt 或 schema 其中之一而不影响另一个时,将二者分开。填写 `KV Cache effect` 时,应区分仅追加增长、稳定重复的前缀、替换既有请求 token 和独立模型请求,并列出会使缓存复用失效、且由本包拥有的变化。“不使缓存失效”仅表示本包保留了已有的可复用前缀;缓存是否可用以及何时淘汰不属于本包契约。[行文标准](../../.agents/skills/dsh-prose-standard/SKILL.md)约束完整性与归属;验证器强制执行机械形状。
|
||||
|
||||
没有上下文效果或仅有消费方拥有路径的包使用 [`SENTENCE_MODEL_EXPERIENCE`](../../scripts/verify-package-readme-model-experience.ts) 中经过审计的 `None, as ` 或 `Indirectly, through ` 语句;与模型无关的通用包可以改为加入 `NO_MODEL_EXPERIENCE_SECTION`。两种情况都不要展开为对另一个包工作的描述。limitations [allowlist](../../scripts/verify-package-readme-limitations.ts) 独立管理。[Model Experience RFC](../rfc/implemented/process/2026-07-12-package-model-experience-contract.md) 记录了设计动机。
|
||||
没有上下文效果或仅有消费方拥有路径的包使用 [`SENTENCE_MODEL_EXPERIENCE`](../../scripts/verify-package-readme-model-experience.ts) 中经过审计的 `None, as ` 或 `Indirectly, through ` 语句,随后添加非空的 `**KV Cache effect**` 字段;与模型无关的通用包可以改为加入 `NO_MODEL_EXPERIENCE_SECTION`。两种情况都不要展开为对另一个包工作的描述。limitations [allowlist](../../scripts/verify-package-readme-limitations.ts) 独立管理。[Model Experience RFC](../rfc/implemented/process/2026-07-12-package-model-experience-contract.md) 记录了设计动机。
|
||||
|
||||
## 5. 验证
|
||||
|
||||
|
||||
@@ -4,28 +4,28 @@ Status: implemented
|
||||
|
||||
## Problem
|
||||
|
||||
A package README can explain APIs and runtime mechanics without answering the question that dominates an agent harness's behavior and cost: what from this package reaches a model request, under which conditions, and how long those tokens remain. The omission is especially hard to audit in a plugin architecture. A consumer may turn a backend result into a tool message, a policy plugin may replace success with an error, compaction may remove old history, and an agent-scoped registration may change one agent's prompt or schemas while leaving every other agent unchanged. Reading only the nominally model-facing packages therefore misses real context effects, while reading source across every dependency is too expensive for routine review.
|
||||
A package README can explain APIs and runtime mechanics without answering the questions that dominate an agent harness's behavior and cost: what from this package reaches a model request, under which conditions, how long those tokens remain, and whether later requests preserve a reusable KV-cache prefix. The omission is especially hard to audit in a plugin architecture. A consumer may turn a backend result into a tool message, a policy plugin may replace success with an error, compaction may remove old history, and an agent-scoped registration may change one agent's prompt or schemas while leaving every other agent unchanged. Reading only the nominally model-facing packages therefore misses real context effects, while reading source across every dependency is too expensive for routine review.
|
||||
|
||||
## Decision
|
||||
|
||||
Every workspace package README with a model-facing or model-adjacent contract ends with the canonical [Model Experience section](../../../cookbook/adding-a-package.md#4-write-the-package-readme), immediately before `## Known Limitations and Deferred Work`; a package on the no-limitations allowlist ends with Model Experience itself. An audited model-agnostic generic package omits the section through `NO_MODEL_EXPERIENCE_SECTION`.
|
||||
|
||||
Packages with direct, conditional, capped, lifetime, multi-surface, or auxiliary-model effects use one H3 per context surface. Each names what the relevant model receives and when, then classifies the token effect. Stable package-owned text is quoted exactly: system-prompt prose and other long literals use a nested H4 plus `markdown` fence, while short literals stay inline with named interpolation placeholders. Tool-schema surfaces link their anchored section in the generated [tool catalog](../../../tool-catalog.md) and state only composition or configuration deltas; runtime-only definitions explain why the catalog omits them. Data-dependent and provider-owned text is summarized. Agent-scoped visibility is explicit, and prompt and schema surfaces remain separate when scoping can hide one without the other.
|
||||
Packages with direct, conditional, capped, lifetime, multi-surface, or auxiliary-model effects use one H3 per context surface. Each names what the relevant model receives and when, classifies the token effect, and states the KV-cache effect. The cache field distinguishes append-only growth, a stable repeated prefix, replacement of earlier tokens, and an independent model request; it names every package-owned configuration, scope, lifecycle, compaction, or routing change that can alter the request before newly appended content. “Does not invalidate” means the package preserves an already-reusable prefix, not that a provider promises a cache hit or retention period. Stable package-owned text is quoted exactly: system-prompt prose and other long literals use a nested H4 plus `markdown` fence, while short literals stay inline with named interpolation placeholders. Tool-schema surfaces link their anchored section in the generated [tool catalog](../../../tool-catalog.md) and state only composition or configuration deltas; runtime-only definitions explain why the catalog omits them. Data-dependent and provider-owned text is summarized. Agent-scoped visibility is explicit, and prompt and schema surfaces remain separate when scoping can hide one without the other.
|
||||
|
||||
A package with no model-context effect, or one path rendered entirely by another package, uses the verifier's audited one-sentence form: `None, as ` or `Indirectly, through `. Pure transport and keyless test-support packages use the none form when they create no model-bound content. Provider backends use the indirect form even when they cap or filter data, and wiring bundles use it when named children own every effect. These sentences locate the contribution without restating the consumer. Structured sections likewise document only package-owned inputs, transformations, and deltas.
|
||||
A package with no model-context effect, or one path rendered entirely by another package, uses the verifier's audited short form: one sentence beginning `None, as ` or `Indirectly, through ` followed by a `**KV Cache effect**` field. Pure transport and keyless test-support packages use the none form when they create no model-bound content. Provider backends use the indirect form even when they cap or filter data, and wiring bundles use it when named children own every effect. These sections locate the contribution and disclaim direct cache invalidation without restating the consumer. Structured sections likewise document only package-owned inputs, transformations, and deltas.
|
||||
|
||||
`verify-package-readme-model-experience` discovers package manifests and validates the three classifications, canonical final-section order, required fields, concrete literal evidence, nested verbatim blocks, and anchored tool-catalog links. It runs in `doc-sync` and the parallel gate runner. Review still owns coverage, link relevance, and factual accuracy.
|
||||
`verify-package-readme-model-experience` discovers package manifests and validates the three classifications, canonical final-section order, required model-view, token, and KV-cache fields, concrete literal evidence, nested verbatim blocks, and anchored tool-catalog links. It runs in `doc-sync` and the parallel gate runner. Review still owns coverage, link relevance, and factual accuracy.
|
||||
|
||||
## Alternatives considered
|
||||
|
||||
- **Document only packages that register prompts or tools** — rejected because backends, policy plugins, adapters, persistence, scoping, and compaction change the content or lifetime of tokens without owning a model-facing schema.
|
||||
- **Generate one central context-cost catalog from source** — rejected because an AST can find registrations but cannot infer semantic conditions such as history retention, output truncation, parent-versus-child visibility, or an auxiliary model boundary. The package README is the implementation-local contract; a central copy would add another drift surface.
|
||||
- **Require numeric token counts** — rejected because exact counts depend on the selected model tokenizer, adapter serialization, configuration, and runtime data. The stable contract is the growth shape: fixed per request, conditional per call, retained, replaced, capped, or zero-direct.
|
||||
- **Use a three-column table** — rejected because exact source text and conditional result shapes make cells dense and difficult to scan. Repeated subsections give each context surface readable vertical space while preserving the same fields.
|
||||
- **Use a table** — rejected because exact source text and conditional result shapes make cells dense and difficult to scan. Repeated subsections give each context surface readable vertical space while preserving the same fields.
|
||||
- **Allow every zero-impact package to omit the section** — rejected because unconstrained absence is ambiguous between an audited zero and forgotten documentation. Omission is reserved for model-agnostic generic packages named with a reason in the verifier; model-adjacent zero-impact packages keep one explicit sentence.
|
||||
- **Require the full structured form for audited zero or simple indirect packages** — rejected because it repeats labels around one fact. A gated sentence preserves explicit coverage without the ceremony.
|
||||
- **Require the full structured form for audited zero or simple indirect packages** — rejected because it repeats labels around one fact. A gated sentence plus cache field preserves explicit coverage without the ceremony.
|
||||
- **Convention without a gate** — rejected because a repo-wide contract must also cover every future package; review memory cannot reliably detect an omitted README section.
|
||||
|
||||
## Consequences
|
||||
|
||||
A reviewer can start at any model-facing or model-adjacent package and see its contribution to the conversation model, child models, and auxiliary calls without reconstructing the full plugin graph. Token-budget work can distinguish repeated request overhead from data-dependent history, and agent-scoped changes have an explicit documentation checkpoint. Package authors maintain one or more compact context-surface blocks or one classified sentence whenever model-visible behavior changes; audited generic packages carry no irrelevant model boilerplate. The structured fields do not promise provider-exact token counts; measurements remain model- and workload-specific, while the documented growth and visibility contract stays stable.
|
||||
A reviewer can start at any model-facing or model-adjacent package and see its contribution to the conversation model, child models, and auxiliary calls without reconstructing the full plugin graph. Token-budget work can distinguish repeated request overhead from data-dependent history, while cache-sensitive work can identify append-only paths and the earliest package-owned prefix mutation. Agent-scoped changes have an explicit documentation checkpoint. Package authors maintain one or more compact context-surface blocks or one classified short form whenever model-visible behavior changes; audited generic packages carry no irrelevant model boilerplate. The structured fields do not promise provider-exact token counts or cache hits; measurements remain model-, provider-, and workload-specific, while the documented growth, visibility, and prefix-stability contract stays stable.
|
||||
+1
-1
@@ -14,5 +14,5 @@ Naming notes:
|
||||
- `src/types.ts` contains only types — no runtime code.
|
||||
- Tests live at package level under `tests/`, not `src/__tests__/`.
|
||||
- A package's README and JSDoc are part of the change: altered behavior (config keys, defaults, error codes, wire fields) updates them in the same commit. `doc-sync` gates what it can; apply [dsh-prose-standard](../.agents/skills/dsh-prose-standard/SKILL.md) for complete, concise prose and verify accuracy against code.
|
||||
- Package READMEs document model/token effects using the [canonical Model Experience format](../docs/cookbook/adding-a-package.md#4-write-the-package-readme).
|
||||
- Package READMEs document model, token, and KV-cache effects using the [canonical Model Experience format](../docs/cookbook/adding-a-package.md#4-write-the-package-readme).
|
||||
- Package READMEs put durable consumer gaps and non-obvious maintainer constraints under `## Known Limitations and Deferred Work`; ordinary cleanup stays in its TODO or RFC. Packages with none use a justified [allowlist entry](../scripts/verify-package-readme-limitations.ts) ([rationale](../docs/rfc/implemented/process/2026-07-10-readme-known-limitations-gate.md)).
|
||||
@@ -31,6 +31,8 @@ Design surveyed against the bash tools of Claude Code, OpenCode, Codex, and pi;
|
||||
|
||||
Indirectly, through `dsh-tool-bash`, which renders this executor's bounded stdout/stderr tails, background-process deltas, spill-file paths, and infrastructure failures.
|
||||
|
||||
**KV Cache effect**: No direct invalidation; the named consumer owns any request-prefix changes.
|
||||
|
||||
## Known Limitations and Deferred Work
|
||||
|
||||
- **Unconfined by itself** — this executor always runs commands with the harness process's authority; deployments needing confinement compose [`dsh-bash-sandbox`](../bash-sandbox/README.md), while per-call allow/deny/ask policy belongs on `tools/pre-execute`.
|
||||
|
||||
@@ -42,18 +42,24 @@ The keyless consumer-integration proofs are `tests/bwrap.e2e.ts`, `tests/landloc
|
||||
|
||||
**Token effect**: Small fixed schema increment on requests where `bash` is visible; mode switches add no context tokens.
|
||||
|
||||
**KV Cache effect**: Prefix-stable while the executor advertises the same sandbox capabilities. Changing those capabilities alters the `bash` schema and may invalidate reuse from that definition; per-session mode switches do not.
|
||||
|
||||
### Bash tool result, indirectly
|
||||
|
||||
**What the model sees**: After ordinary bounded output, a denied call appends exactly `[sandbox: file access denied under <mode> mode]`. When escalation is available it next appends `[sandbox: escalation available — retry this exact command once with sandbox_permissions (the narrowest wider mode that suffices) + justification; the approval prompt asks the user]`. A settled background runner failure instead appends `[sandbox: the sandbox runner itself failed under <mode> mode — the command did not run; this is a sandbox problem, not a command failure]`.
|
||||
|
||||
**Token effect**: Zero additional tokens on an unremarkable allowed run beyond ordinary output. Denial or failure adds the quoted conditional marker, retained until compaction.
|
||||
|
||||
**KV Cache effect**: Append-only; newly visible content follows the reusable request prefix and does not invalidate existing KV-cache entries.
|
||||
|
||||
### Bash tool error, indirectly
|
||||
|
||||
**What the model sees**: If no runner can enforce a confined mode, the foreground call propagates the [`SANDBOX_UNAVAILABLE` error owned by `dsh-sandbox`](../../sandbox/sandbox/README.md#confinement-error-indirectly). For an execution-time runner failure, this backend supplies the first stderr line as its detail.
|
||||
|
||||
**Token effect**: Conditional error text is visible for that call and retained in history until compaction.
|
||||
|
||||
**KV Cache effect**: Append-only; newly visible content follows the reusable request prefix and does not invalidate existing KV-cache entries.
|
||||
|
||||
## Known Limitations and Deferred Work
|
||||
|
||||
- **Confinement covers file effects only** — network access and process visibility are unchanged, so the modes are not a general-purpose security sandbox.
|
||||
|
||||
@@ -37,6 +37,8 @@ The seam also owns the per-session mode override vocabulary: the log-only `'bash
|
||||
|
||||
Indirectly, through `dsh-tool-bash`, which turns executor output and sandbox facts into guidance and retained tool-result tokens.
|
||||
|
||||
**KV Cache effect**: No direct invalidation; the named consumer owns any request-prefix changes.
|
||||
|
||||
## Known Limitations and Deferred Work
|
||||
|
||||
- **No interactive-input vocabulary** — `stdin` is written once at spawn and closed; the seam has no channel to feed a running task and no PTY session concept.
|
||||
|
||||
@@ -77,6 +77,8 @@ For sandboxing executors, each call resolves mode as one-shot escalation, then s
|
||||
|
||||
**Token effect**: Small fixed input cost per request while the plugin is active, unchanged by sandbox mode or mode switches.
|
||||
|
||||
**KV Cache effect**: Prefix-stable while the registration scope and prompt text are unchanged. Plugin activation or disposal may invalidate reuse from this prompt section; sandbox mode switches do not.
|
||||
|
||||
#### Bash guidance
|
||||
|
||||
```markdown
|
||||
@@ -89,24 +91,32 @@ Check the [exit code: N] marker on every bash result; investigate failures befor
|
||||
|
||||
**Token effect**: Fixed schema cost on every request where the tools are visible; sandbox support adds the escalation fields and its conditional description paragraph.
|
||||
|
||||
**KV Cache effect**: Prefix-stable while visibility, background support, and executor sandbox capabilities are unchanged. A restriction, config change, or executor change may invalidate reuse from the first changed tool definition.
|
||||
|
||||
### Foreground result
|
||||
|
||||
**What the model sees**: The renderer emits the data-dependent stdout tail, then optional `[stderr]` and the stderr tail. With no output it emits exactly `(no output)`. Conditional lines are exactly `[output truncated; full output: <path-or-(unavailable)>]`, `[sandbox: file access denied under <mode> mode]`, `[timed out after <timeoutMs>ms]`, `[killed by signal: <signal>]`, and `[exit code: <exitCode>]`; the sandbox escalation and runner-failure lines are quoted in [`dsh-bash-sandbox`](../bash-sandbox/README.md).
|
||||
|
||||
**Token effect**: Zero result tokens before a call. Output is bounded per stream, while each emitted line remains in history until compaction.
|
||||
|
||||
**KV Cache effect**: Append-only; newly visible content follows the reusable request prefix and does not invalidate existing KV-cache entries.
|
||||
|
||||
### Background task context and results
|
||||
|
||||
**What the model sees**: Start returns exactly `started background task <taskId>`. This producer supplies incremental process output, optional `[some output was dropped from memory; full output: <paths-or-(unavailable)>]`, sandbox facts, and terminal detail such as `exit code: <exitCode>` or `signal: <signal>` to the generic task runtime. [`dsh-tool-tasks`](../../tasks/tool-tasks/README.md) owns the visible status line, completion notice, listing, and cancellation response.
|
||||
|
||||
**Token effect**: The start acknowledgement is small and retained; collected output is data-dependent and bounded by the executor's stream buffers. Consuming reads do not repeat prior output.
|
||||
|
||||
**KV Cache effect**: Append-only; newly visible content follows the reusable request prefix and does not invalidate existing KV-cache entries.
|
||||
|
||||
### Tool errors
|
||||
|
||||
**What the model sees**: Validation and policy failures are normalized as `Error: <message>`. This package's stable messages are `invalid command: expected a non-empty string`, `invalid description: expected a non-empty string`, `invalid timeoutMs: expected a positive number, got <value>`, `invalid escalation: sandbox_permissions requires a justification`, `invalid escalation: justification is only valid together with sandbox_permissions`, `invalid justification: expected a non-empty sentence`, `background execution is disabled for this bash tool`, `background tasks unavailable: load @deepseek-ai/dsh-tasks and @deepseek-ai/dsh-tool-tasks`, `sandbox_permissions is not available in this composition (no sandboxing executor to escalate)`, `sandbox escalation to "<mode>" is not strictly wider than this call's current "<mode>" mode`, the approval-availability/rejection/cancellation variants, and `command aborted`.
|
||||
|
||||
**Token effect**: Only the failing call adds these retained tokens; a rejected escalation does not add command output because the command does not run.
|
||||
|
||||
**KV Cache effect**: Append-only; newly visible content follows the reusable request prefix and does not invalidate existing KV-cache entries.
|
||||
|
||||
## Known Limitations and Deferred Work
|
||||
|
||||
- **Replay exit pills parse from result text** — output whose final line happens to be exactly `[exit code: N]` / `[killed by signal: …]` shows a wrong pill on session replay; a display-only known residual.
|
||||
|
||||
@@ -37,6 +37,8 @@ The SDK surface is the default/named `WorkerCodeRuntime` class plus `Config`. Th
|
||||
|
||||
Indirectly, through Code Mode in [`dsh-tools`](../../core/tools/README.md), which renders this worker's capped printed or returned data and exact `[dsh-code-runtime-worker] log capture truncated at <maxLogBytes> bytes` and `… [truncated]` markers into a retained `run_code` result. Binding traffic and worker internals stay outside context.
|
||||
|
||||
**KV Cache effect**: No direct invalidation; the named consumer owns any request-prefix changes.
|
||||
|
||||
## Known Limitations and Deferred Work
|
||||
|
||||
- **OS processes a program spawns survive termination** — `worker.terminate()` ends the thread only, weaker than bash-local's process-group kill; orphan cleanup is a deployment concern until a container backend exists.
|
||||
|
||||
@@ -22,6 +22,8 @@ Semantics every implementation must honor (contract details in the class JSDoc):
|
||||
|
||||
Indirectly, through Code Mode in `dsh-tools`, which exposes `run_code` and returns program logs, values, or failures as retained tool-result tokens.
|
||||
|
||||
**KV Cache effect**: No direct invalidation; the named consumer owns any request-prefix changes.
|
||||
|
||||
## Known Limitations and Deferred Work
|
||||
|
||||
- **`run()` is one-shot** — `logs` arrive only on the resolved `CodeRunResult`; the seam exposes no streaming-log or progress surface for a live program's output.
|
||||
|
||||
@@ -60,6 +60,8 @@ Loading the plugin registers `ctx.compact`. With `auto: true` (the default) it c
|
||||
|
||||
**Token effect**: The replacement reduces future input history rather than appending a second copy. The summary remains until a later compaction replaces it; one oversized indivisible unit can still exceed the budget.
|
||||
|
||||
**KV Cache effect**: Replacing rather than append-only. Each checkpoint invalidates reuse from the first replaced history token; the unchanged request prefix before that range remains reusable.
|
||||
|
||||
#### Conversation checkpoint preamble
|
||||
|
||||
```markdown
|
||||
@@ -72,12 +74,16 @@ This is an automatically generated checkpoint condensing an earlier span of the
|
||||
|
||||
**Token effect**: This is a separate model call with data-dependent input and `maxTokens`-capped output. Convergence retries can pay this cost more than once.
|
||||
|
||||
**KV Cache effect**: Independent of the conversation request cache. An auxiliary call can reuse an exact transcript prefix, while a different selected range or rendering invalidates reuse from its first changed token.
|
||||
|
||||
### Auxiliary summarizer system prompt
|
||||
|
||||
**What the model sees**: The summarization model receives the checkpoint-writing instruction below.
|
||||
|
||||
**Token effect**: Fixed auxiliary input cost plus the data-dependent transcript on every summarization attempt.
|
||||
|
||||
**KV Cache effect**: Prefix-stable for auxiliary calls while this instruction and the summarizer route are unchanged. Changing either starts a different prefix; transcript changes occur after the instruction.
|
||||
|
||||
#### Auxiliary summarizer system prompt
|
||||
|
||||
```markdown
|
||||
|
||||
@@ -65,12 +65,16 @@ Subclass `CompactService`, implement `compactIfNeeded` and `compactRegion`, and
|
||||
|
||||
**Token effect**: Zero direct tokens from this interface. A backend trades many retained history tokens for one summary and leaves the recent tail unchanged.
|
||||
|
||||
**KV Cache effect**: A successful backend replacement invalidates reuse from the first shadowed history token; the seam itself does not alter a request.
|
||||
|
||||
### Transcript supplied to a compaction consumer
|
||||
|
||||
**What the model sees**: `renderTranscript()` joins entries with one blank line and renders them exactly as `User: <content>`, `Assistant: <content>`, `Tool result (call <callId>): <content>`, `Tool error (call <callId>): <content>`, `[Context: <content>]`, or `[Steering: <content>]`. Non-text blocks render exactly as `[reasoning: <text>]`, `[tool-call: <name>(<arguments>)]`, `[tool-result: <content>]`, `[tool-result]`, or `[<block-type>]`.
|
||||
|
||||
**Token effect**: Data-dependent input tokens are paid only by the auxiliary model or consumer that requests this transcript; the conversation model does not receive a duplicate transcript.
|
||||
|
||||
**KV Cache effect**: No conversation-cache invalidation. A consumer's auxiliary request can reuse only the exact prefix produced by this rendering; changed or compacted entries invalidate reuse from their first difference.
|
||||
|
||||
## Known Limitations and Deferred Work
|
||||
|
||||
- **No model-facing consumer tier yet** — `@deepseek-ai/dsh-tool-compact` (the `/compact` tool) is deferred; compaction is reachable only via direct `ctx.compact` calls or a backend's auto listener.
|
||||
|
||||
@@ -36,6 +36,8 @@ The time reading stays in derived conversation history until a later compaction
|
||||
|
||||
**Token effect**: Each injected two-line message accumulates until compaction shadows it. A positive interval reduces additions; omission or `0` adds one for every eligible preparation attempt.
|
||||
|
||||
**KV Cache effect**: Append-only; newly visible content follows the reusable request prefix and does not invalidate existing KV-cache entries.
|
||||
|
||||
#### First step
|
||||
|
||||
```markdown
|
||||
|
||||
@@ -82,6 +82,8 @@ Instruction content is read through `streamText()` under `maxSourceBytes`, even
|
||||
|
||||
**Token effect**: The rendered baseline is frozen and resent on every request in that loop instance. `maxBytes` bounds the complete message, broader files are omitted before the most-specific file is truncated, and an empty chain contributes zero tokens.
|
||||
|
||||
**KV Cache effect**: Prefix-stable within one loop instance because the baseline is frozen. A new or resumed instance recomposes it, so instruction, precedence, cwd, candidate, or byte-budget changes may invalidate reuse from the first changed baseline token.
|
||||
|
||||
#### Baseline instruction template
|
||||
|
||||
```markdown
|
||||
@@ -104,6 +106,8 @@ Instructions from: AGENTS.md
|
||||
|
||||
**Token effect**: Each discovered scope adds bounded history tokens until compaction. Unchanged content is suppressed by visible session state plus version/digest comparison, and Code Mode defers the same message until after the outer `run_code` result.
|
||||
|
||||
**KV Cache effect**: Append-only; newly visible content follows the reusable request prefix and does not invalidate existing KV-cache entries.
|
||||
|
||||
#### Additional instruction template
|
||||
|
||||
```markdown
|
||||
@@ -122,6 +126,8 @@ These instructions apply to work under `packages/app`. Use them as guidance when
|
||||
|
||||
**Token effect**: Each confirmed change or removal is one retained history message bounded by `maxBytes`. Provider failures add no message, and an update omitted by the budget remains eligible for a later filesystem touch.
|
||||
|
||||
**KV Cache effect**: Append-only; newly visible content follows the reusable request prefix and does not invalidate existing KV-cache entries.
|
||||
|
||||
#### Removal notice
|
||||
|
||||
```markdown
|
||||
|
||||
@@ -40,18 +40,24 @@ Namespace plugin: named exports `name` / `inject` / `Config` / `apply`, no defau
|
||||
|
||||
**Token effect**: Fixed schema cost on every request in that tool view.
|
||||
|
||||
**KV Cache effect**: Prefix-stable while this tool view is unchanged. Scoping or plugin lifecycle changes that hide these definitions may invalidate reuse from the first changed schema token.
|
||||
|
||||
### 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. Its broad API/event reports omit JSDoc; `name` with `what: "api"` or `what: "events"` returns one exact target with its original JSDoc. 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.
|
||||
|
||||
**KV Cache effect**: Append-only; newly visible content follows the reusable request prefix and does not invalidate existing KV-cache entries.
|
||||
|
||||
### 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.
|
||||
|
||||
**KV Cache effect**: Mounting or unmounting a prompt or tool contribution changes later request prefixes and may invalidate reuse from the first changed contribution; an unchanged mount set remains prefix-stable.
|
||||
|
||||
## 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).
|
||||
|
||||
@@ -76,18 +76,24 @@ Everything that goes beyond "call the model, run the tools, repeat" belongs to p
|
||||
|
||||
**Token effect**: System text, schemas, and prefix are paid again on every step. Per-agent scoping chooses the initial contributions, while the authoritative assembly waterfall can alter the final request and makes its listener responsible for protocol coherence.
|
||||
|
||||
**KV Cache effect**: Append-only only while system text, schemas, session prefix, and earlier history remain byte-identical under the same provider and model route. A token-bearing assembly rewrite or composition change may invalidate reuse from the first altered request token.
|
||||
|
||||
### Retained message history
|
||||
|
||||
**What the model sees**: Accepted user messages, assistant messages, tool calls and results, injected context, and steering are logged and sent on later steps. Raw stream chunks, lifecycle boundaries, and other log-only events are excluded.
|
||||
|
||||
**Token effect**: Input grows with every surface message until a compaction replacement shadows older nodes; a multi-step tool turn resends the accumulated prefix and history each step.
|
||||
|
||||
**KV Cache effect**: Ordinary history growth is append-only and preserves reusable entries. A surface replacement or compaction invalidates reuse from the first shadowed history token.
|
||||
|
||||
### Undispatched calls after cancellation
|
||||
|
||||
**What the model sees**: If a later request replays an aborted step, each tool call that cancellation prevented from dispatching has the error result text `Error: tool call skipped because the step was aborted before execution`.
|
||||
|
||||
**Token effect**: One fixed error result per skipped call remains in history until compaction shadows it.
|
||||
|
||||
**KV Cache effect**: Append-only; each synthetic result follows the reusable request prefix and does not invalidate existing KV-cache entries.
|
||||
|
||||
## Known Limitations and Deferred Work
|
||||
|
||||
- **Classification is unary** — calls whose safety depends on comparing siblings or resources must remain exclusive ([rationale](../../../docs/rfc/implemented/feature/2026-07-10-parallel-tool-call-execution.md)).
|
||||
|
||||
@@ -75,12 +75,16 @@ The handle every plugin programs against:
|
||||
|
||||
**Token effect**: Accepted content becomes retained history or a repeated session prefix; blocked content contributes no request tokens. Size is caller- and plugin-dependent.
|
||||
|
||||
**KV Cache effect**: Accepted history and steering are append-only; a blocked submission sends no request. A session prefix remains stable within its loop instance, while a new or resumed instance may establish a different prefix.
|
||||
|
||||
### Agent-scoped request composition
|
||||
|
||||
**What the model sees**: Registrations through `agent.ctx` can shadow prompt sections or tools and can install agent-only interceptors during unpublished setup.
|
||||
|
||||
**Token effect**: The package adds zero tokens itself; scoped contributions affect only that agent and disappear on disposal.
|
||||
|
||||
**KV Cache effect**: Prefix-stable while an agent's scoped registrations are unchanged. Setup or reload that changes prompt sections, tool definitions, or request listeners may invalidate reuse from the first affected request token.
|
||||
|
||||
## Known Limitations and Deferred Work
|
||||
|
||||
- **Initiator scope is process-local** — workers, child processes, HTTP, durable queues, and restarts materialize any required identity explicitly.
|
||||
|
||||
@@ -89,18 +89,24 @@ Every `SessionEvent` carries two optional top-level fields (structural metadata)
|
||||
|
||||
**Token effect**: Appended surface entries are resent on later steps. A `replace` surface operation removes the shadowed entries from future inputs without deleting their raw log records.
|
||||
|
||||
**KV Cache effect**: Appended surface entries preserve reusable prefixes. A `replace` operation invalidates reuse from the first shadowed message even though the underlying event log stays append-only.
|
||||
|
||||
### Crash-repair result
|
||||
|
||||
**What the model sees**: If a persisted turn ended with unanswered tool calls, each synthetic error result contains exactly `Tool call interrupted by a crash; no result was recorded.`
|
||||
|
||||
**Token effect**: Zero tokens in an intact session. Each repaired call adds this retained error text on resume.
|
||||
|
||||
**KV Cache effect**: Append-only; newly visible content follows the reusable request prefix and does not invalidate existing KV-cache entries.
|
||||
|
||||
### Logged request header
|
||||
|
||||
**What the model sees**: The session reconstructs the system prompt, tool schemas, call config, and session prefix that the loop actually sent. Header events do not add a second copy to message history; the prefix is prepended outside `deriveMessages()`.
|
||||
|
||||
**Token effect**: Zero duplicate tokens from logging. The reconstructed prefix, system text, and schemas still incur their normal per-request cost.
|
||||
|
||||
**KV Cache effect**: Logging causes no invalidation, and exact reconstruction preserves request-prefix identity. A later header with changed prefix, prompt, or schemas may invalidate reuse from its first difference.
|
||||
|
||||
## Known Limitations and Deferred Work
|
||||
|
||||
- **Session branching/tree** (pi-style entry tree) — deferred unless needed beyond boundary-based `fork()`.
|
||||
|
||||
@@ -48,6 +48,8 @@ Design rationale: [the prompt-variables RFC](../../../docs/rfc/implemented/archi
|
||||
|
||||
**Token effect**: Identity is a fixed per-request cost. Persona and plugin text are repeated per request and scale with their rendered content.
|
||||
|
||||
**KV Cache effect**: Prefix-stable while identity, persona, variables, section text, and order render identically. Any change may invalidate reuse from the first changed system-prompt token.
|
||||
|
||||
#### Harness identity
|
||||
|
||||
```markdown
|
||||
@@ -60,6 +62,8 @@ You are an AI agent powered by the DeepSeek Harness SDK.
|
||||
|
||||
**Token effect**: Schema tokens repeat on every request. Restricting a tool removes its entire schema cost for that agent but not a separate prompt section; reordering changes cache shape but not semantic content.
|
||||
|
||||
**KV Cache effect**: Prefix-stable while the visible schema set, rendering, and order are unchanged. Registration, restriction, or reordering may invalidate reuse from the first changed schema token.
|
||||
|
||||
## Known Limitations and Deferred Work
|
||||
|
||||
- **Deployment-authored prompt text is config/composition only** — this plugin owns the global persona default, creator plugins may register agent-scoped shadows, and other sections come from the plugin that owns the fact; there is no end-user prompt-editing API.
|
||||
|
||||
@@ -123,12 +123,16 @@ The agent loop groups consecutive `parallel` calls into a bounded rolling pool a
|
||||
|
||||
**Token effect**: Fixed per-request cost proportional to the visible definitions. Restrictions that hide tools remove their entire schema cost for that agent.
|
||||
|
||||
**KV Cache effect**: Prefix-stable while visible definitions and their order are unchanged. Registration, disposal, or scoped restriction may invalidate reuse from the first changed schema token.
|
||||
|
||||
### Code Mode schema and system prompt
|
||||
|
||||
**What the model sees**: Code Mode exposes the generated [`run_code` schema](../../../docs/tool-catalog.md#deepseek-aidsh-tools), the SDK instructions below, and the generated exact `declare const tools` block. `both` exposes normal schemas and this Code Mode surface.
|
||||
|
||||
**Token effect**: Fixed per-request cost proportional to the visible definitions. Code Mode trades end-tool schemas for generated SDK text plus one transport schema rather than promising a universal reduction.
|
||||
|
||||
**KV Cache effect**: Prefix-stable while the Code Mode selection, generated SDK, transport schema, and visible tool set are unchanged. Mode or filter changes may invalidate reuse from the first changed prompt or schema token.
|
||||
|
||||
#### Code Mode SDK instructions
|
||||
|
||||
```markdown
|
||||
@@ -150,6 +154,8 @@ The available tools:
|
||||
|
||||
**Token effect**: Arguments, results, and additional context are data-dependent and resent until compaction. Restrictions that hide tools also remove their schemas before the model can call them.
|
||||
|
||||
**KV Cache effect**: Append-only; newly visible content follows the reusable request prefix and does not invalidate existing KV-cache entries.
|
||||
|
||||
## Known Limitations and Deferred Work
|
||||
|
||||
- **Concurrency policy is not an event seam** — `executionMode()` reads the resolved tool definition directly; plugins can only declare a classifier on definitions they own.
|
||||
|
||||
@@ -55,6 +55,8 @@ All diagnostics go to **stderr** — stdout is the protocol.
|
||||
|
||||
Indirectly, through `dsh-agent-spine-demo` and `dsh-acp`, which compose each ACP agent's prompt, tools, and message history; this app bundle adds no model-bound content itself.
|
||||
|
||||
**KV Cache effect**: No direct invalidation; the named consumer owns any request-prefix changes.
|
||||
|
||||
## Known Limitations and Deferred Work
|
||||
|
||||
- **JSONL persistence is baked in** — config chooses its root but cannot select a different backend; that requires a sibling entry or differently composed app package.
|
||||
|
||||
@@ -56,6 +56,8 @@ A YAML include can deduplicate config but cannot own a bin or provide front-door
|
||||
|
||||
Indirectly, through `dsh-system-prompt`, `dsh-tool-skill`, `dsh-tool-bash`, and `dsh-tools`, which this bundle mounts without adding model-bound wrapper content.
|
||||
|
||||
**KV Cache effect**: No direct invalidation; the named consumer owns any request-prefix changes.
|
||||
|
||||
## Known Limitations and Deferred Work
|
||||
|
||||
- **The spine set is fixed in code** — `apply()` mounts every child unconditionally (including `tool-bash`); no config excludes or replaces one, so swapping the loop or dropping a spine member means composing a different bundle.
|
||||
|
||||
@@ -59,6 +59,8 @@ The headless-agent leaf supplies local bash, filesystem, skill, subagent, workfl
|
||||
|
||||
**Token effect**: The task, prompt sections, tool schemas, assistant output, and tool results consume tokens on each model step. JSON event streaming and final rendering add no model tokens; delegated child work has its own model usage and is not included in the parent result's `usage` total.
|
||||
|
||||
**KV Cache effect**: Tool-round history is append-only while the one-shot agent's prompt, schemas, model route, and session prefix remain fixed. Changing that composition establishes a different request prefix; JSON output mode has no cache effect.
|
||||
|
||||
## Known Limitations and Deferred Work
|
||||
|
||||
- **One fresh top-level session per process** — its workspace cwd is the launch directory; there is no resume, second prompt, stdin context, or concurrent top-level session in this app.
|
||||
|
||||
@@ -20,6 +20,8 @@ stdout carries only JSON-RPC frames. The bin and boot guards diagnose on stderr,
|
||||
|
||||
Indirectly, through the plugins loaded from the external `cordis.yml`, which own every model-bound prompt, schema, message, and result; this bin adds none of its own.
|
||||
|
||||
**KV Cache effect**: No direct invalidation; the named consumer owns any request-prefix changes.
|
||||
|
||||
## Known Limitations and Deferred Work
|
||||
|
||||
- **The bin cannot prove that the config serves JSON-RPC** — a valid config with no `dsh-jsonrpc` entry boots successfully and serves nothing.
|
||||
|
||||
@@ -83,12 +83,16 @@ Swap `llm-deepseek` for a `mock-llm` leaf plugin and you have the echo demo —
|
||||
|
||||
**Token effect**: Child prompt and schema costs repeat per request; user input and tool history grow until compaction. Terminal banners, logger output, cards, and rendered transcripts add zero model tokens.
|
||||
|
||||
**KV Cache effect**: User and tool history is append-only while the composed prompt, schemas, child model route, and session prefix remain fixed. A composition change or compaction may invalidate reuse from its first changed token; terminal rendering has no cache effect.
|
||||
|
||||
### Human-answer result
|
||||
|
||||
**What the model sees**: Through `dsh-tool-ask-user`, successful terminal answers use that package's exact compact JSON shape. Interruption becomes exactly `Error: ask_user_question was interrupted before the user answered`; a closed stdin becomes `Error: ask_user_question cannot be answered because stdin is closed`.
|
||||
|
||||
**Token effect**: Only a completed or failed tool call adds retained result tokens; prompts printed while waiting are terminal-only.
|
||||
|
||||
**KV Cache effect**: Append-only; newly visible content follows the reusable request prefix and does not invalidate existing KV-cache entries.
|
||||
|
||||
## Known Limitations and Deferred Work
|
||||
|
||||
- **One pre-created `main` agent drives the selected terminal UI** — there is no multi-session or concurrent-agent surface in this app; a run is one conversation.
|
||||
|
||||
@@ -25,6 +25,8 @@ The package-root SDK surface is the default/named `LocalFileSystem` class plus `
|
||||
|
||||
Indirectly, through [`dsh-tool-fs`](../tool-fs/README.md), which renders this provider's line-windowed UTF-8 content, mutation acknowledgements, and exact provider messages in capped retained results while versions, atomic-write mechanics, and directory metadata remain internal.
|
||||
|
||||
**KV Cache effect**: No direct invalidation; the named consumer owns any request-prefix changes.
|
||||
|
||||
## Known Limitations and Deferred Work
|
||||
|
||||
- **`config.cwd` is not a sandbox** — it is a resolution default, not containment: absolute paths and `..` escape it. Enforce containment with a stricter `ctx.fs` backend or a permission plugin on the `tools/execute` waterfall ([capability-seam RFC](../../../docs/rfc/implemented/architecture/2026-06-17-filesystem-capability-seam.md#consequences)).
|
||||
|
||||
@@ -55,6 +55,8 @@ Because the plugin influences the world only through events, removing it does no
|
||||
|
||||
**Token effect**: Zero tokens on allowed operations beyond the ordinary tool result. A denial adds the small retained error result and avoids any success payload.
|
||||
|
||||
**KV Cache effect**: Append-only; newly visible content follows the reusable request prefix and does not invalidate existing KV-cache entries.
|
||||
|
||||
## Known Limitations and Deferred Work
|
||||
|
||||
- **Observed state does not survive a session resume** — persistence of the `WeakMap` record is deferred, so a resumed session must re-read files before guarded writes/edits.
|
||||
|
||||
@@ -48,6 +48,8 @@ This package declares three events (see the generated [events catalog](../../../
|
||||
|
||||
Indirectly, through `dsh-tool-fs`, which renders provider text and errors as bounded, retained filesystem tool results.
|
||||
|
||||
**KV Cache effect**: No direct invalidation; the named consumer owns any request-prefix changes.
|
||||
|
||||
## Known Limitations and Deferred Work
|
||||
|
||||
- **Text-only by contract** — backends reject binary/non-UTF-8 content with `FS_NOT_TEXT`; binary-safe operations are a deliberate deferral of [the tool-schemas RFC](../../../docs/rfc/implemented/feature/2026-06-17-filesystem-tool-schemas.md).
|
||||
|
||||
@@ -53,6 +53,8 @@ Search failures carry the package-owned `SearchError` (a `HarnessError` subclass
|
||||
|
||||
**Token effect**: Fixed guidance cost per request while the plugin is active.
|
||||
|
||||
**KV Cache effect**: Prefix-stable while the plugin scope and guidance text are unchanged. Activation or disposal may invalidate reuse from this prompt section.
|
||||
|
||||
#### Glob guidance
|
||||
|
||||
```markdown
|
||||
@@ -71,18 +73,24 @@ Use the grep tool — not shell grep or rg — to search file contents. Use read
|
||||
|
||||
**Token effect**: Fixed schema cost on every request where the tools are visible.
|
||||
|
||||
**KV Cache effect**: Prefix-stable while tool visibility and definitions are unchanged. Registration lifecycle or scoped restrictions may invalidate reuse from the first changed schema token.
|
||||
|
||||
### Results and spill notices
|
||||
|
||||
**What the model sees**: `glob` returns one path per line; `grep` groups `Line <line>: <preview>` matches beneath each path. Empty searches return `No files found` or `No matches found`. A capped result ends with its omission count plus the spill locator and backend retrieval hint, or says the complete result could not be saved.
|
||||
|
||||
**Token effect**: Inline paths and matches are bounded by `globMaxResults`, `grepMaxMatches`, and `grepMaxLineBytes`; the call and retained result remain in history until compaction.
|
||||
|
||||
**KV Cache effect**: Append-only; newly visible content follows the reusable request prefix and does not invalidate existing KV-cache entries.
|
||||
|
||||
### Tool errors
|
||||
|
||||
**What the model sees**: Failures are normalized as `Error: <message>` with structured `SEARCH_INVALID_PATTERN`, `SEARCH_FAILED`, `SEARCH_RAW_OUTPUT_OVERFLOW`, or `SEARCH_ABORTED` metadata for callers.
|
||||
|
||||
**Token effect**: Only a failing call adds these retained tokens.
|
||||
|
||||
**KV Cache effect**: Append-only; newly visible content follows the reusable request prefix and does not invalidate existing KV-cache entries.
|
||||
|
||||
## Known Limitations and Deferred Work
|
||||
|
||||
- **Search and file access have no shared-workspace proof** — returned paths are follow-up-readable only when the bash workdir and filesystem root denote the same workspace; the package performs no runtime cross-service validation.
|
||||
|
||||
@@ -58,6 +58,8 @@ The package root exports only the Cordis plugin contract (`name`, `inject`, `Con
|
||||
|
||||
**Token effect**: Fixed guidance cost per request while the plugin is active, even when a restriction hides one or more tools.
|
||||
|
||||
**KV Cache effect**: Prefix-stable while the plugin scope and guidance text are unchanged. Tool restrictions do not remove this section, but plugin activation or disposal may invalidate reuse from it.
|
||||
|
||||
#### Read guidance
|
||||
|
||||
```markdown
|
||||
@@ -82,24 +84,32 @@ Use the edit tool for targeted changes to existing UTF-8 text files. It replaces
|
||||
|
||||
**Token effect**: Fixed schema cost on every request in that tool view.
|
||||
|
||||
**KV Cache effect**: Prefix-stable while the visible tool definitions and order are unchanged. Registration lifecycle or scoped restrictions may invalidate reuse from the first changed schema token.
|
||||
|
||||
### Read result
|
||||
|
||||
**What the model sees**: A successful read is exactly `<path><displayPath></path>`, newline, `<type>file</type>`, newline, `<content>`, numbered lines as `<lineNumber>: <text>`, a blank line, one footer, and `</content>`. The footer is exactly `(Output capped. Showing lines <start>-<end>. Use offset=<next> to continue.)`, `(Showing lines <start>-<end> of <total>. Use offset=<next> to continue.)`, or `(End of file - total <total> lines)`. A long line ends exactly `... (line truncated to <max> chars)`.
|
||||
|
||||
**Token effect**: Read output is capped by `readLimit`, `readMaxLineLength`, and `readMaxBytes`; the retained call and result are resent until compaction.
|
||||
|
||||
**KV Cache effect**: Append-only; newly visible content follows the reusable request prefix and does not invalidate existing KV-cache entries.
|
||||
|
||||
### Write and edit results
|
||||
|
||||
**What the model sees**: Write returns the exact five-line envelope `<path><displayPath></path>`, `<type>file</type>`, `<content>`, `Created file` or `Updated file`, then `</content>`. Edit returns exactly `The file <displayPath> has been updated successfully.` or, for `replace_all`, `The file <displayPath> has been updated. All occurrences were successfully replaced.` The full write or replacement text remains in the assistant tool-call arguments.
|
||||
|
||||
**Token effect**: Success text is small, but large mutation arguments and any result are resent until compaction.
|
||||
|
||||
**KV Cache effect**: Append-only; newly visible content follows the reusable request prefix and does not invalidate existing KV-cache entries.
|
||||
|
||||
### Tool errors
|
||||
|
||||
**What the model sees**: Failures are normalized as `Error: <message>`. This package's stable validation and read messages are `file_path must be a non-empty string`, `limit must be less than or equal to <max>`, `old_string must be a non-empty string`, `old_string and new_string must differ`, `cannot read "<path>": not found`, `cannot read "<path>": not a regular file`, and `offset <offset> is out of range for "<path>" (<total> lines)`; provider and policy templates are quoted in their package READMEs.
|
||||
|
||||
**Token effect**: Only a failing call adds these retained tokens.
|
||||
|
||||
**KV Cache effect**: Append-only; newly visible content follows the reusable request prefix and does not invalidate existing KV-cache entries.
|
||||
|
||||
## Known Limitations and Deferred Work
|
||||
|
||||
- **No model-facing directory listing ships** — `ctx.fs.listDir` serves provider code such as skill discovery, while the sibling [`dsh-tool-fs-search`](../tool-fs-search/) package supplies bash-backed `glob` and `grep` rather than extending the filesystem seam.
|
||||
|
||||
@@ -44,6 +44,8 @@ Unit suites drive a real agent loop against a mock adapter (no network) and cove
|
||||
|
||||
**Token effect**: Zero tokens before the threshold. The reminder is retained history for that agent.
|
||||
|
||||
**KV Cache effect**: Append-only; newly visible content follows the reusable request prefix and does not invalidate existing KV-cache entries.
|
||||
|
||||
#### First-threshold reminder
|
||||
|
||||
```markdown
|
||||
@@ -56,6 +58,8 @@ You are repeating the exact same tool call with identical arguments. Carefully a
|
||||
|
||||
**Token effect**: Each reminder is retained history; `argumentsPreviewChars` bounds its data-dependent argument text, while agents keep independent counters.
|
||||
|
||||
**KV Cache effect**: Append-only; newly visible content follows the reusable request prefix and does not invalidate existing KV-cache entries.
|
||||
|
||||
#### Later-threshold reminder
|
||||
|
||||
```markdown
|
||||
|
||||
@@ -33,6 +33,8 @@ Like every event they must sit inside an open turn. The mid-turn points (`PreToo
|
||||
|
||||
Indirectly, through `dsh-hooks-claude` and `dsh-hooks-codex`, which can turn parsed hook output into prompt context, blocked outcomes, or continuation feedback.
|
||||
|
||||
**KV Cache effect**: No direct invalidation; the named consumer owns any request-prefix changes.
|
||||
|
||||
## Known Limitations and Deferred Work
|
||||
|
||||
- **`HookOutput.updatedInput` is parsed but not honored** — input rewrite is a deferred consistency-design problem ([the pre-tool-input-rewrite RFC](../../../docs/rfc/proposed/feature/2026-06-30-pre-tool-input-rewrite.md)); a bridge logs + warns when a hook sets it. See `src/types.ts` for the full contracts.
|
||||
|
||||
@@ -60,12 +60,16 @@ Injected context carries an explicit `{ kind: 'plugin', plugin: 'hooks-claude' }
|
||||
|
||||
**Token effect**: No cost when hooks return no context. Hook text is data-dependent, logged, and resent in later conversation requests until compaction.
|
||||
|
||||
**KV Cache effect**: Append-only; newly visible content follows the reusable request prefix and does not invalidate existing KV-cache entries.
|
||||
|
||||
### Blocked prompt or tool outcome
|
||||
|
||||
**What the model sees**: Provider-supplied reasons pass through verbatim. When absent, a blocked prompt uses exactly `blocked by UserPromptSubmit hook`, a denied tool becomes `Error: blocked by PreToolUse hook`, blocked post-tool feedback is exactly `blocked by PostToolUse hook`, and a blocking stop adds steering exactly `continue: blocked by Stop hook`. `systemMessage` and `updatedInput` are logged or warned but are not model-visible in this implementation.
|
||||
|
||||
**Token effect**: Blocking a prompt removes that prompt's request tokens; denial or feedback adds the retained fallback or provider text; forced continuation pays another full request.
|
||||
|
||||
**KV Cache effect**: A blocked prompt sends no request and invalidates nothing. Denial, feedback, and forced-continuation context append after the reusable prefix without rewriting it.
|
||||
|
||||
## Known Limitations and Deferred Work
|
||||
|
||||
- **Unsupported hook events (23 of Claude Code's current 30):** `Setup`, `InstructionsLoaded`, `UserPromptExpansion`, `MessageDisplay`, `PermissionRequest`, `PostToolUseFailure`, `PostToolBatch`, `PermissionDenied`, `Notification`, `TaskCreated`, `TaskCompleted`, `StopFailure`, `TeammateIdle`, `ConfigChange`, `CwdChanged`, `FileChanged`, `WorktreeCreate`, `WorktreeRemove`, `PreCompact`, `PostCompact`, `SessionEnd`, `Elicitation`, and `ElicitationResult`. Config for these events is parsed but never dispatched. The comparison baseline is Claude Code's [official hook-event reference](https://code.claude.com/docs/en/hooks#hook-events).
|
||||
|
||||
@@ -64,12 +64,16 @@ Injected context carries an explicit `{ kind: 'plugin', plugin: 'hooks-codex' }`
|
||||
|
||||
**Token effect**: No cost when hooks return no context. Hook text is data-dependent, logged, and resent until compaction.
|
||||
|
||||
**KV Cache effect**: Append-only; newly visible content follows the reusable request prefix and does not invalidate existing KV-cache entries.
|
||||
|
||||
### Blocked prompt or tool outcome
|
||||
|
||||
**What the model sees**: Provider-supplied reasons pass through verbatim. When absent, a blocked prompt uses exactly `blocked by UserPromptSubmit hook`, a denied tool becomes `Error: blocked by PreToolUse hook`, blocked post-tool feedback is exactly `blocked by PostToolUse hook`, and a blocking stop adds steering exactly `continue: blocked by Stop hook`. Codex `systemMessage` is not surfaced.
|
||||
|
||||
**Token effect**: Blocking a prompt removes its request tokens; denial or feedback adds the retained fallback or provider text; forced continuation pays another full request.
|
||||
|
||||
**KV Cache effect**: A blocked prompt sends no request and invalidates nothing. Denial, feedback, and forced-continuation context append after the reusable prefix without rewriting it.
|
||||
|
||||
## Known Limitations and Deferred Work
|
||||
|
||||
- **Unsupported hook events (5 of Codex's current 10):** `PermissionRequest`, `PreCompact`, `PostCompact`, `SubagentStart`, and `SubagentStop`. Config for these events is silently dropped during parsing. The comparison baseline is Codex's [official hook reference](https://learn.chatgpt.com/docs/hooks).
|
||||
|
||||
@@ -56,12 +56,16 @@ Unit suites run against a local `node:http` mock SSE server (no network). Real-A
|
||||
|
||||
**Token effect**: Provider tokenization governs exact input. Conditional reasoning passback increases tool-round-trip context, while dropping other reasoning avoids paying those tokens again; cache-read usage is reported when available.
|
||||
|
||||
**KV Cache effect**: An unchanged assembled prefix is eligible for DeepSeek cache reuse, which this adapter reports in usage. A model-route change or any upstream prompt, schema, prefix, or history change may prevent reuse from the first changed token; reasoning passback appends during tool round trips.
|
||||
|
||||
### DeepSeek response
|
||||
|
||||
**What the model sees**: Reasoning, text, and raw-string tool arguments are translated into harness chunks for the loop to log and assemble.
|
||||
|
||||
**Token effect**: Generated tokens follow provider thinking and effort settings plus the request's `maxTokens`; only loop-retained blocks affect later input.
|
||||
|
||||
**KV Cache effect**: Loop-retained response blocks append to the next request and preserve its earlier reusable prefix; dropped blocks have no later cache effect. Changing the provider or model selects a different cache domain.
|
||||
|
||||
## Known Limitations and Deferred Work
|
||||
|
||||
- **`tool_choice` is not mapped** — not part of the core vocabulary (MVP cut, shared with the pi-ai twin).
|
||||
|
||||
@@ -67,12 +67,16 @@ Unit tests use pi-ai catalog models redirected to local mock servers and cover p
|
||||
|
||||
**Token effect**: Provider tokenization governs exact input. Conversion adds no model-visible text; replay metadata may let a native API reuse provider-side state.
|
||||
|
||||
**KV Cache effect**: Conversion preserves logical request order without adding text, while the selected provider's serialization and replay state determine reuse. Changing adapter instance, provider, model, or any upstream request token may prevent reuse from the first difference.
|
||||
|
||||
### Provider response
|
||||
|
||||
**What the model sees**: pi-ai events become harness reasoning, text, tool-call, usage, and finish chunks. Parsed tool arguments cross the harness boundary as raw JSON strings.
|
||||
|
||||
**Token effect**: Generated content affects later inputs only after the loop records it. pi-ai folds reasoning tokens into output usage when the provider does not report them separately.
|
||||
|
||||
**KV Cache effect**: Recorded response content appends to the next request and does not invalidate its earlier reusable prefix. Unrecorded transport metadata and usage accounting do not affect cache identity.
|
||||
|
||||
## Known Limitations and Deferred Work
|
||||
|
||||
- **Catalog membership is required** — custom model ids that are absent from the installed pi-ai catalog fail with `UNKNOWN_MODEL`, even when a provider profile supplies a custom endpoint.
|
||||
|
||||
@@ -58,6 +58,8 @@ Two adapters implement `LlmAdapter` on different internals: [`@deepseek-ai/dsh-l
|
||||
|
||||
None, as this adapter registry forwards an already assembled request without adding or changing any model-bound text, schema, or message.
|
||||
|
||||
**KV Cache effect**: Pass-through; the registry preserves the assembled request prefix, while the selected adapter and provider own cache reuse and routing boundaries.
|
||||
|
||||
## Known Limitations and Deferred Work
|
||||
|
||||
- **No default retry/caching/rate-limit policy ships in this service** — `llm/stream` remains the call-wrapper seam; the agent loop separately offers proven model-request failures to `agent/request-error`, whose default preserves the original failure.
|
||||
|
||||
@@ -42,6 +42,8 @@ Both plugins have usable defaults. A deployment with a different capacity config
|
||||
|
||||
Indirectly, through consumers such as `dsh-compact-basic`; the service itself adds no prompt, message, schema, tool, or model call.
|
||||
|
||||
**KV Cache effect**: No direct invalidation; the named consumer owns any request-prefix changes.
|
||||
|
||||
## Known Limitations and Deferred Work
|
||||
|
||||
- **The fixed heuristic is approximate** — content without reusable provider usage is priced by character count plus structural overhead, not an exact provider tokenizer or request serializer.
|
||||
|
||||
@@ -74,12 +74,16 @@ Every MCP tool has two names: the raw MCP name (sent on the wire in `tools/call`
|
||||
|
||||
**Token effect**: Data-dependent schema cost is paid on every request while the tools are registered. Re-sync replaces rather than accumulates schemas, and the server-qualified name adds tokens to every tool definition and call.
|
||||
|
||||
**KV Cache effect**: Prefix-stable while the discovered tool set and schemas are unchanged. A re-sync that adds, removes, renames, or changes a tool replaces definitions and may invalidate reuse from the first changed schema token.
|
||||
|
||||
### Tool-call history and results
|
||||
|
||||
**What the model sees**: The public tool name and JSON arguments remain in assistant history. Text result blocks are joined with newlines into one retained text result; image, audio, resource, and unsupported blocks become short placeholders, and MCP `isError` results follow the registry's model-visible error path.
|
||||
|
||||
**Token effect**: Arguments and mapped text are retained until compaction. Binary and resource payloads are discarded rather than added to context.
|
||||
|
||||
**KV Cache effect**: Append-only; newly visible content follows the reusable request prefix and does not invalidate existing KV-cache entries.
|
||||
|
||||
## Known Limitations and Deferred Work
|
||||
|
||||
- **Initial discovery is asynchronous** — plugin load does not wait for connection and `listTools()`, so a turn started immediately after boot or HMR can assemble before the MCP tools are registered.
|
||||
|
||||
@@ -25,6 +25,8 @@ Consumers: [`@deepseek-ai/dsh-bash-sandbox`](../../bash/bash-sandbox/); see [the
|
||||
|
||||
Indirectly, through [`dsh-bash-sandbox`](../../bash/bash-sandbox/README.md) and [`dsh-tool-bash`](../../bash/tool-bash/README.md), which render this provider's enforcement and denial facts while the [`dsh-sandbox`](../sandbox/README.md) seam owns the `SANDBOX_UNAVAILABLE` text and runner selection and profiles stay outside context.
|
||||
|
||||
**KV Cache effect**: No direct invalidation; the named consumer owns any request-prefix changes.
|
||||
|
||||
## Known Limitations and Deferred Work
|
||||
|
||||
- **Windows has no runner** — `win32` fails closed with `SANDBOX_UNAVAILABLE`; an AppContainer-family backend is deferred.
|
||||
|
||||
@@ -18,6 +18,8 @@ Implementations: [`@deepseek-ai/dsh-sandbox-local`](../sandbox-local/) (Linux: `
|
||||
|
||||
**Token effect**: Conditional error text is visible for that call and retained in history until compaction.
|
||||
|
||||
**KV Cache effect**: Append-only; newly visible content follows the reusable request prefix and does not invalidate existing KV-cache entries.
|
||||
|
||||
#### Exact error
|
||||
|
||||
```markdown
|
||||
|
||||
@@ -14,6 +14,8 @@ The provider choice is DeepSeek or a custom endpoint backed by `llm-pi-ai`. Deep
|
||||
|
||||
Indirectly, through the generated project composition and its selected runtime plugins.
|
||||
|
||||
**KV Cache effect**: No direct invalidation; the named consumer owns any request-prefix changes.
|
||||
|
||||
## Known Limitations and Deferred Work
|
||||
|
||||
- **TTY-only creation** — flags prefill questions, but the wizard still requires an interactive terminal before it writes a project.
|
||||
@@ -18,6 +18,8 @@ The package root explicitly exports only the objects consumed by `create-sdk` an
|
||||
|
||||
None, as the project domain edits files and never mounts a live agent or model request.
|
||||
|
||||
**KV Cache effect**: None; this package neither assembles nor sends a provider request.
|
||||
|
||||
## Known Limitations and Deferred Work
|
||||
|
||||
- **Commit is not transactional across files** — external edits are detected before each write, but a later failure does not roll back files already written.
|
||||
@@ -25,6 +25,8 @@ The root library exports `startSDK`, `runSDK`, and the `SdkBootArgs`/`SdkBootCon
|
||||
|
||||
Indirectly, through the project `cordis.yml` tree loaded by `start` or `dev`.
|
||||
|
||||
**KV Cache effect**: No direct invalidation; the named consumer owns any request-prefix changes.
|
||||
|
||||
## Known Limitations and Deferred Work
|
||||
|
||||
- **Launcher arguments are schema-free** — `start` and `dev` preserve Node `parseArgs()` output rather than validating project-specific flags.
|
||||
@@ -40,6 +40,8 @@ The plugin buffers frozen session events and drains them on flush or disposal. A
|
||||
|
||||
**Token effect**: Zero live-request tokens. A resumed agent pays for retained history and its current envelope, plus the quoted repair result for each interrupted call.
|
||||
|
||||
**KV Cache effect**: JSONL storage does not mutate live request prefixes. A resumed loop can reuse provider cache only when its reconstructed history, current envelope, and model route match; crash-repair results append.
|
||||
|
||||
## Known Limitations and Deferred Work
|
||||
|
||||
- **Only the current `SESSION_FORMAT_VERSION` (v0) loads** — the on-disk format is pre-release/unstable: a breaking format change is absorbed at v0 and non-current logs are rejected; there is no migration.
|
||||
|
||||
@@ -41,6 +41,8 @@ Like the JSONL backend, the plugin also installs the `session/event` → buffer
|
||||
|
||||
**Token effect**: Zero live-request tokens. Resume restores retained history and pays the current envelope, plus the quoted repair result for each interrupted call.
|
||||
|
||||
**KV Cache effect**: SQLite storage does not mutate live request prefixes. A resumed loop can reuse provider cache only when its reconstructed history, current envelope, and model route match; crash-repair results append.
|
||||
|
||||
## Known Limitations and Deferred Work
|
||||
|
||||
- **`DatabaseSync` is synchronous** — every append transaction blocks the event loop for its duration; acceptable for local stores, a throughput ceiling for busy multi-session servers.
|
||||
|
||||
@@ -61,6 +61,8 @@ Re-exported from `dsh-session`: `SessionHeader` (immutable session metadata: `ve
|
||||
|
||||
**Token effect**: Zero tokens during ordinary persistence. Resume restores retained history cost and pays the current request envelope normally; each repaired call adds the quoted retained error text.
|
||||
|
||||
**KV Cache effect**: Persistence does not mutate live request prefixes. A resumed loop can reuse provider cache only when its reconstructed history, current envelope, and model route match; crash-repair results append without rewriting earlier history.
|
||||
|
||||
## Known Limitations and Deferred Work
|
||||
|
||||
- **No deletion or retention surface** — the seam is `create`/`append`/`load`/`list` only; pruning stored sessions is out-of-band backend maintenance.
|
||||
|
||||
@@ -26,6 +26,8 @@ Persistence is optional and may mount or unmount dynamically. Cross-corpus listi
|
||||
|
||||
None, as this trusted query service returns cloned session records only to its callers and registers no model-facing prompt, schema, tool, or message.
|
||||
|
||||
**KV Cache effect**: None; this package neither assembles nor sends a provider request.
|
||||
|
||||
## Known Limitations and Deferred Work
|
||||
|
||||
- **No caller authorization** — this is trusted context-wide infrastructure; a future model tool or UI must constrain which sessions its caller may inspect.
|
||||
|
||||
@@ -40,6 +40,8 @@ Skills can be single-level directory bundles (`<name>/SKILL.md`) or flat Markdow
|
||||
|
||||
Indirectly, through `dsh-tool-skill`, which renders this provider's invocable names and capped descriptions into the session-prefix catalog and a selected instruction body plus resource-base guidance into retained tool history while paths, provider ranks, and disabled skills remain hidden.
|
||||
|
||||
**KV Cache effect**: No direct invalidation; the named consumer owns any request-prefix changes.
|
||||
|
||||
## Known Limitations and Deferred Work
|
||||
|
||||
- **Discovery is one level deep** — only `<root>/<name>/SKILL.md` and `<root>/<name>.md` are recognized; nested skill trees and package manifests are ignored.
|
||||
|
||||
@@ -39,6 +39,8 @@ The registry does not render model guidance or register model-facing tools. [`@d
|
||||
|
||||
Indirectly, through `dsh-tool-skill`, which renders provider summaries into the session prefix and loaded instructions into retained tool results.
|
||||
|
||||
**KV Cache effect**: No direct invalidation; the named consumer owns any request-prefix changes.
|
||||
|
||||
## Known Limitations and Deferred Work
|
||||
|
||||
- **Completed catalogs have no TTL or watcher invalidation** — a provider's underlying files or remote data can change without a registration revision, so a cached cwd stays stale until eviction or provider/runtime reload.
|
||||
|
||||
@@ -32,6 +32,8 @@ The tool does not call `agent.inject()` in v1. Its result is already recorded as
|
||||
|
||||
**Token effect**: Repeated input cost scales with skill count and `catalogDescriptionMaxLength`; no catalog tokens are sent when the list is empty or the tool is hidden or shadowed.
|
||||
|
||||
**KV Cache effect**: Prefix-stable within a loop instance once the session prefix is composed. A new or resumed instance with different providers, skills, descriptions, visibility, or catalog limits may invalidate reuse from the first changed catalog token.
|
||||
|
||||
#### Skill catalog template
|
||||
|
||||
```markdown
|
||||
@@ -52,12 +54,16 @@ If the user names a skill, or the task clearly matches a skill's description, ca
|
||||
|
||||
**Token effect**: Fixed schema cost per request where the tool is visible.
|
||||
|
||||
**KV Cache effect**: Prefix-stable while the tool definition and visibility are unchanged. Shadowing, restrictions, or plugin lifecycle changes may invalidate reuse from this schema.
|
||||
|
||||
### Tool result
|
||||
|
||||
**What the model sees**: A successful call uses the result template and the provider-managed, directory, URL, or opaque resource guidance below.
|
||||
|
||||
**Token effect**: Loaded instructions are data-dependent tool-result tokens, resent on later steps until compaction; no duplicate `agent.inject()` copy is made.
|
||||
|
||||
**KV Cache effect**: Append-only; newly visible content follows the reusable request prefix and does not invalidate existing KV-cache entries.
|
||||
|
||||
#### Skill result template
|
||||
|
||||
```markdown
|
||||
@@ -106,6 +112,8 @@ Load referenced resources only as needed.
|
||||
|
||||
**Token effect**: Only a failing call adds these retained tokens.
|
||||
|
||||
**KV Cache effect**: Append-only; newly visible content follows the reusable request prefix and does not invalidate existing KV-cache entries.
|
||||
|
||||
## Known Limitations and Deferred Work
|
||||
|
||||
- **The catalog omits `whenToUse`, source, and provider metadata** — routing is based only on name and a capped description; `whenToUse` remains provider metadata and is not rendered by the loaded wrapper either.
|
||||
|
||||
@@ -22,6 +22,8 @@ Files land at `<root>/session-<hash>/<random>-<safeName>`:
|
||||
|
||||
Indirectly, through spill consumers that render the local path and `read`/`grep` retrieval guidance.
|
||||
|
||||
**KV Cache effect**: No direct invalidation; the named consumer owns any request-prefix changes.
|
||||
|
||||
## Known Limitations and Deferred Work
|
||||
|
||||
- **Local spill files persist until external cleanup** — the backend has no session-lifecycle deletion or age-based retention policy, because persisted, resumed, and forked sessions may still reference a path.
|
||||
|
||||
@@ -40,6 +40,8 @@ The policy sees only the FINAL formatted tool result — not a tool's internal r
|
||||
|
||||
**Token effect**: A successful replacement is at most `maxInlineBytes` UTF-8 bytes and remains in history until compaction; the full spill text is not resent to the model.
|
||||
|
||||
**KV Cache effect**: Append-only; newly visible content follows the reusable request prefix and does not invalidate existing KV-cache entries.
|
||||
|
||||
## Known Limitations and Deferred Work
|
||||
|
||||
- **Only final plain-text results are spillable** — mixed-content results, blocked feedback, and `read` pass through; provider truncation or tool-owned retention that happened earlier cannot be recovered here.
|
||||
|
||||
@@ -30,6 +30,8 @@ See the [tool output spill RFC](../../../docs/rfc/implemented/architecture/2026-
|
||||
|
||||
Indirectly, through spill consumers that render a backend locator and retrieval guidance.
|
||||
|
||||
**KV Cache effect**: No direct invalidation; the named consumer owns any request-prefix changes.
|
||||
|
||||
## Known Limitations and Deferred Work
|
||||
|
||||
- **The seam has no retrieval or deletion API** — consumers can only render the backend's locator and guidance; lifecycle and access semantics remain backend-specific.
|
||||
|
||||
@@ -67,12 +67,16 @@ Keyless tests drive a scripted ACP subprocess over real stdio. The with-key e2e
|
||||
|
||||
**Token effect**: The child pays for an independent full context and its own multi-step history. These tokens never enter the parent's context.
|
||||
|
||||
**KV Cache effect**: Independent of the parent request cache. Each ACP child can reuse only prefixes identical under its own provider, model, composition, and history; child steps otherwise grow append-only.
|
||||
|
||||
### Parent tool result, indirectly
|
||||
|
||||
**What the model sees**: Through `dsh-tool-subagent`, the parent receives only the child's final streamed assistant text or that consumer's exact stop-reason error, not intermediate messages or tool traffic. A request already cancelled before publication becomes exactly `Error: subagent request was aborted before the ACP child started`; other start failures pass through as `Error: <message>`.
|
||||
|
||||
**Token effect**: Parent input grows only by the final result or error, which is data-dependent and retained until compaction. This provider adds no parent schema itself.
|
||||
|
||||
**KV Cache effect**: Append-only; newly visible content follows the reusable request prefix and does not invalidate existing KV-cache entries.
|
||||
|
||||
## Known Limitations and Deferred Work
|
||||
|
||||
- **A fresh process per run** — persistent-process pooling is a future optimization ([the seam RFC](../../../docs/rfc/implemented/feature/2026-06-21-subagent-capability-seam.md)).
|
||||
|
||||
@@ -31,12 +31,16 @@ See [`dsh-subagent-spawn`](../subagent-spawn/README.md) for the run lifecycle, m
|
||||
|
||||
**Token effect**: Forking duplicates retained completed history into separate child requests; the child then accumulates its own tokens independently. Persona changes repeated prompt cost, filtering changes schema or generated SDK cost, and a first-turn fork has no inherited history.
|
||||
|
||||
**KV Cache effect**: The child may reuse the inherited byte-identical prefix under the same provider and model. Persona, tool-filter, generated-SDK, or route changes may invalidate reuse before inherited history; later child history is append-only.
|
||||
|
||||
### Parent tool result, indirectly
|
||||
|
||||
**What the model sees**: The parent receives only the child's own final output through `dsh-tool-subagent`, not the inherited prefix or intermediate work.
|
||||
|
||||
**Token effect**: Parent input grows by one data-dependent final result retained until compaction.
|
||||
|
||||
**KV Cache effect**: Append-only; newly visible content follows the reusable request prefix and does not invalidate existing KV-cache entries.
|
||||
|
||||
## Known Limitations and Deferred Work
|
||||
|
||||
- **Runs expose no `sendMessage`/`resume`** — the optional runtime capabilities are absent on in-process runs.
|
||||
|
||||
@@ -48,12 +48,16 @@ A clean turn that never commits the required structured value reports `error`; t
|
||||
|
||||
**Token effect**: Child input is isolated from the parent and grows through the child's own steps. A persona changes repeated prompt text; filtering changes schema or generated SDK cost but not independently registered guidance.
|
||||
|
||||
**KV Cache effect**: Independent of the parent request cache. The child's later history is append-only, while persona, tool-filter, generated-SDK, provider, or model changes establish a different child prefix.
|
||||
|
||||
### Structured-output system prompt, schema, and results
|
||||
|
||||
**What the model sees**: A structured run adds the structured-output instruction below. It also adds a child-scoped `structured_output` definition with exact description `Report your final structured result. Call this exactly once, when your answer is complete; the arguments must match this tool's parameter schema exactly.` and the requested schema. This runtime-only definition is outside the generated shipped [tool package map](../../../docs/tool-catalog.md#tool-package-map). Success returns `Structured output recorded.`; a later call becomes ``Error: structured output already recorded: the run is complete, so `<tool>` is not executed``.
|
||||
|
||||
**Token effect**: Fixed instruction and capability tokens are paid only by that child. Result text enters the child history, while the captured value alone becomes the parent result.
|
||||
|
||||
**KV Cache effect**: Prefix-stable inside the child while the structured-output instruction and schema are unchanged. Changing the schema or capability may invalidate the child's cache from that early segment; results append in child and parent histories.
|
||||
|
||||
#### Structured-output instruction
|
||||
|
||||
```markdown
|
||||
@@ -66,12 +70,16 @@ When you have your final answer, you MUST report it by calling the `structured_o
|
||||
|
||||
**Token effect**: Zero tokens on a successful start; only the failed parent tool call retains this text.
|
||||
|
||||
**KV Cache effect**: Append-only; newly visible content follows the reusable request prefix and does not invalidate existing KV-cache entries.
|
||||
|
||||
### Parent result, indirectly
|
||||
|
||||
**What the model sees**: The driver extracts only the child's own last assistant output or captured structured value; seeded parent messages and intermediate child work do not become the result.
|
||||
|
||||
**Token effect**: The parent receives one data-dependent result through the consumer; all other child tokens stay in the child session.
|
||||
|
||||
**KV Cache effect**: Append-only; newly visible content follows the reusable request prefix and does not invalidate existing KV-cache entries.
|
||||
|
||||
## Known Limitations and Deferred Work
|
||||
|
||||
- **Runs expose no `sendMessage`/`resume`** — the optional runtime capabilities are absent on in-process runs.
|
||||
|
||||
@@ -26,12 +26,16 @@ Spawn advertises `{ outputSchema: true, depthLimit: true, toolFilter: true, pers
|
||||
|
||||
**Token effect**: The child pays for a new independent context and history; no parent-history tokens are duplicated. Persona changes this child's repeated prompt cost, while filtering changes its schema or generated SDK cost.
|
||||
|
||||
**KV Cache effect**: Independent of the parent request cache. Child history grows append-only, while persona, tool-filter, generated-SDK, provider, or model changes establish a different child prefix.
|
||||
|
||||
### Parent tool result, indirectly
|
||||
|
||||
**What the model sees**: Through `dsh-tool-subagent`, the parent receives only the child's final output or stop-reason error.
|
||||
|
||||
**Token effect**: Parent input grows by one data-dependent result retained until compaction.
|
||||
|
||||
**KV Cache effect**: Append-only; newly visible content follows the reusable request prefix and does not invalidate existing KV-cache entries.
|
||||
|
||||
## Known Limitations and Deferred Work
|
||||
|
||||
- **Runs expose no `sendMessage`/`resume`** — the optional runtime capabilities are absent on in-process runs.
|
||||
|
||||
@@ -41,6 +41,8 @@ A per-run isolated config directory for an external CLI child (the target of `CL
|
||||
|
||||
Indirectly, through process-based subagent backends, whose child composition is constrained by credential scrubbing and isolated config directories.
|
||||
|
||||
**KV Cache effect**: No direct invalidation; the named consumer owns any request-prefix changes.
|
||||
|
||||
## Known Limitations and Deferred Work
|
||||
|
||||
- **The credential scrub is name-based** — only variables matching `KEY` / `SECRET` / `TOKEN` are removed; differently named secrets such as `PASSWORD` pass through unless the backend supplies a stricter environment.
|
||||
|
||||
@@ -66,6 +66,8 @@ The model-facing tool collects synchronously by default: it awaits the child res
|
||||
|
||||
Indirectly, through `dsh-tool-subagent`, which renders provider-specific schemas and foreground or generic-background results while child working context remains child-only.
|
||||
|
||||
**KV Cache effect**: No direct invalidation; the named consumer owns any request-prefix changes.
|
||||
|
||||
## Known Limitations and Deferred Work
|
||||
|
||||
- **Runtime steering and continuation are seam-only capabilities** — `sendMessage` and `resume` have no model-facing consumer in the current tool.
|
||||
|
||||
@@ -36,18 +36,24 @@ Foreground and background calls are exclusive. Children may share the parent's w
|
||||
|
||||
**Token effect**: Fixed schema cost per parent request; each provider instance adds one schema.
|
||||
|
||||
**KV Cache effect**: Prefix-stable while provider instances, names, descriptions, and schemas are unchanged. Provider registration lifecycle may invalidate parent reuse from the first changed tool definition.
|
||||
|
||||
### Foreground result
|
||||
|
||||
**What the model sees**: The call retains the description and prompt. Success contains only the child's final text; other outcomes become `Error: <message>`. Intermediate child steps stay out of the parent.
|
||||
|
||||
**Token effect**: The prompt and result remain in parent history until compaction; child working context remains in the child.
|
||||
|
||||
**KV Cache effect**: Append-only; newly visible content follows the reusable request prefix and does not invalidate existing KV-cache entries.
|
||||
|
||||
### Background task result
|
||||
|
||||
**What the model sees**: Start returns exactly `started background subagent task <id>`. The generic task surface provides later status, final output, cancellation responses, and notices.
|
||||
|
||||
**Token effect**: The acknowledgement is retained; final output enters parent history only when collected or injected.
|
||||
|
||||
**KV Cache effect**: Append-only; newly visible content follows the reusable request prefix and does not invalidate existing KV-cache entries.
|
||||
|
||||
## Known Limitations and Deferred Work
|
||||
|
||||
- **Background runs expose final output only** — intermediate child steps stay in the child session.
|
||||
|
||||
@@ -46,6 +46,8 @@ Constraints: `suite.ts` imports vitest, so the package entry is importable only
|
||||
|
||||
None, as this test-only harness records, normalizes, and compares ACP transcripts without changing the agent's assembled model request.
|
||||
|
||||
**KV Cache effect**: None; this package neither assembles nor sends a provider request.
|
||||
|
||||
## Known Limitations and Deferred Work
|
||||
|
||||
- **Session harvest is JSONL-only** — `runScenario` collects persisted `.jsonl` logs, so an example composed over the SQLite persistence backend has no snapshot path.
|
||||
|
||||
@@ -22,6 +22,8 @@ Tests of injection failures, partial topology, service load order, or service te
|
||||
|
||||
None, as this test-only composition helper neither drives nor modifies model requests.
|
||||
|
||||
**KV Cache effect**: None; this package neither assembles nor sends a provider request.
|
||||
|
||||
## Known Limitations and Deferred Work
|
||||
|
||||
- **Only the mandatory prerequisite spine is shared** — adapters, optional plugins, `AgentLoop`, agents, and Context teardown remain caller-owned so scenario-specific ordering stays visible.
|
||||
@@ -56,6 +56,8 @@ A seeded or forked session arrives with events already in its log because constr
|
||||
|
||||
None, as this observer only validates events and frozen requests and never rewrites prompts, schemas, messages, or streams.
|
||||
|
||||
**KV Cache effect**: None; this package neither assembles nor sends a provider request.
|
||||
|
||||
## Known Limitations and Deferred Work
|
||||
|
||||
- **The request-reconstructability assertion covers loop-built requests only** — hand-built one-shots (e.g. compaction's summarize call) carry no live `sessionId` marker and are skipped.
|
||||
|
||||
@@ -56,6 +56,8 @@ Named `name` / `inject` / `Config` / `apply`, with **no default export**: the co
|
||||
|
||||
None, as this keyless test adapter sends no request to a provider model; it only replays recorded assistant chunks into the test loop.
|
||||
|
||||
**KV Cache effect**: None; this package neither assembles nor sends a provider request.
|
||||
|
||||
## Known Limitations and Deferred Work
|
||||
|
||||
- **First-call-order script binding assumes sequential delegation** — a cut that runs sibling subagents concurrently (or a compaction summarize call landing mid-run) would bind live sessions to recorded scripts non-deterministically; a stronger keying is deferred until such a scenario exists (`XXX(concurrent-subagents)`).
|
||||
|
||||
@@ -10,6 +10,8 @@ This is support-tier test infrastructure, not product API.
|
||||
|
||||
None, as this test-only harness boots example processes and inspects their streams without changing an assembled model request.
|
||||
|
||||
**KV Cache effect**: None; this package neither assembles nor sends a provider request.
|
||||
|
||||
## Known Limitations and Deferred Work
|
||||
|
||||
- **Built mode requires a prior build** — the config must also resolve every named package upward through `examples/node_modules`.
|
||||
|
||||
@@ -26,6 +26,8 @@ See the [task type catalog](../../../docs/core-data-structures/tasks.md) and [ru
|
||||
|
||||
Indirectly, through producer plugins and [`dsh-tool-tasks`](../tool-tasks/README.md), which render task ids, output, status, cancellation, and completion notices.
|
||||
|
||||
**KV Cache effect**: No direct invalidation; the named consumer owns any request-prefix changes.
|
||||
|
||||
## Known Limitations and Deferred Work
|
||||
|
||||
- **Tasks are process-local** — durable or cross-restart execution needs a separate lifecycle.
|
||||
|
||||
@@ -31,6 +31,8 @@ A default above the cap fails at load.
|
||||
|
||||
**Token effect**: Small fixed input cost per request while active.
|
||||
|
||||
**KV Cache effect**: Prefix-stable while the plugin scope and guidance text are unchanged. Activation or disposal may invalidate reuse from this prompt section.
|
||||
|
||||
#### Background-task guidance
|
||||
|
||||
```markdown
|
||||
@@ -43,12 +45,16 @@ Track every background task id you start. You are notified in-session when a tas
|
||||
|
||||
**Token effect**: Fixed schema cost on each request where the tools are visible.
|
||||
|
||||
**KV Cache effect**: Prefix-stable while tool definitions and visibility are unchanged. Registration lifecycle or scoped restrictions may invalidate reuse from the first changed schema token.
|
||||
|
||||
### Results and notices
|
||||
|
||||
**What the model sees**: Reads return output or `(no new output)` followed by `[status: <status>]` and optional detail. An empty list returns `(no background tasks)`. Kill returns `requested cancellation of task <id>` or the existing terminal status. Unreported owned completion uses the notice above.
|
||||
|
||||
**Token effect**: Results and notices remain in parent history until compaction. Stream reads do not repeat consumed output.
|
||||
|
||||
**KV Cache effect**: Append-only; newly visible content follows the reusable request prefix and does not invalidate existing KV-cache entries.
|
||||
|
||||
## Known Limitations and Deferred Work
|
||||
|
||||
- **Completion notices do not wake idle agents** — callers needing an immediate result must use `task_output`.
|
||||
|
||||
@@ -41,6 +41,8 @@ Multiple `tools/execute` listeners compose by cordis registration order. Combine
|
||||
|
||||
**Token effect**: Zero tokens on non-timeout calls. A timeout adds one small retained error result and can prevent a larger late provider result from entering context.
|
||||
|
||||
**KV Cache effect**: Append-only; newly visible content follows the reusable request prefix and does not invalidate existing KV-cache entries.
|
||||
|
||||
## Known Limitations and Deferred Work
|
||||
|
||||
- **Cooperative, never a hard kill** — the deadline only notifies via `exec.signal`; a tool that ignores the signal does not stop on timeout (see § Cooperative, not a hard kill).
|
||||
|
||||
@@ -32,12 +32,16 @@ A function/namespace plugin: it exports `name` / `inject` / `apply` and NO defau
|
||||
|
||||
**Token effect**: Fixed schema cost on every request where the tool is visible.
|
||||
|
||||
**KV Cache effect**: Prefix-stable while the definition and visibility are unchanged. Plugin lifecycle or scoped restrictions may invalidate reuse from this schema.
|
||||
|
||||
### Tool-call history and result
|
||||
|
||||
**What the model sees**: Each assistant tool call retains the entire replacement list in its arguments. Success returns exactly `Updated todo list: <pending> pending, <inProgress> in progress, <completed> completed.` Stable failures are ``Error: invalid todo: `content` must be a non-empty string``, `Error: invalid todos: duplicate content "<content>"`, `Error: invalid todos: at most one task may be in_progress, got <count>`, and `Error: todo_write requires an owning agent session`. The full `todo/write` session event is UI and replay state, not a second model message.
|
||||
|
||||
**Token effect**: Token growth scales with every full list the model submits, and those call arguments remain until compaction. The result itself is small and fixed-shape.
|
||||
|
||||
**KV Cache effect**: Append-only; newly visible content follows the reusable request prefix and does not invalidate existing KV-cache entries.
|
||||
|
||||
## Known Limitations and Deferred Work
|
||||
|
||||
- **Single-owner scope only** — the list belongs to the one calling agent session; subagent/shared/swarm scopes are a deliberate cut (see § Single owner), and a non-agent caller is rejected.
|
||||
|
||||
@@ -98,30 +98,40 @@ The JSON-RPC frames go on stdout, so this plugin MUST run in an example that loa
|
||||
|
||||
**Token effect**: Prompt tokens are data-dependent and remain in that session's history until compaction. Concurrent ACP sessions keep separate contexts.
|
||||
|
||||
**KV Cache effect**: Append-only; newly visible content follows the reusable request prefix and does not invalidate existing KV-cache entries.
|
||||
|
||||
### Human answers and permission decisions
|
||||
|
||||
**What the model sees**: When optional consumers are loaded, ACP form answers become the exact JSON shape documented by `dsh-tool-ask-user`. Failures become `Error: ACP user questions must come from an agent-owned request`, `Error: ACP user question has no matching session`, `Error: ACP elicitation request failed`, `Error: ask_user_question was cancelled by the user`, `Error: ask_user_question returned no answer`, or `Error: ask_user_question was aborted before the user answered`. Permission decisions control whether another tool yields success or denial. ACP tool cards, terminal output, diffs, and streamed session updates are UI-only.
|
||||
|
||||
**Token effect**: Answer, error, and denial text enters context only through the owning tool result; presentation metadata adds zero model tokens.
|
||||
|
||||
**KV Cache effect**: Append-only; newly visible content follows the reusable request prefix and does not invalidate existing KV-cache entries.
|
||||
|
||||
### Permission preset switches
|
||||
|
||||
**What the model sees**: `session/set_config_option` emits no model message itself. When `dsh-permission` is composed, the bridge writes the selected preset through that service; the resulting model-visible policy prompt and change notice belong to [`dsh-user-approval`](../user-approval/README.md), while sandbox-mode effects belong to [`dsh-tool-bash`](../../bash/tool-bash/README.md). The ACP `Permissions` select, its option descriptions, pending idle value, and refreshed config response remain client-only.
|
||||
|
||||
**Token effect**: Zero direct tokens from the ACP option or the log-only `permission/preset` event. Downstream cost is limited to the owning plugins' policy prompt, conditional retained change notice, and any changed tool outcome.
|
||||
|
||||
**KV Cache effect**: The ACP option and log event cause no direct invalidation. The downstream policy-prompt change may invalidate reuse from that system section, while its change notice appends to history.
|
||||
|
||||
### Model switches
|
||||
|
||||
**What the model sees**: The ACP selector itself emits no message. The selected provider/model pair supplies the next step's `{{provider}}` / `{{model}}` prompt variables and request routing together; all other call-config fields continue through the `agent/request` waterfall unchanged.
|
||||
|
||||
**Token effect**: The selector adds no direct tokens. A changed model may tokenize the same retained prompt/history differently, and any persona text that interpolates provider or model changes accordingly.
|
||||
|
||||
**KV Cache effect**: Switching provider or model selects a different cache domain. If the persona interpolates either value, the rendered system prompt also changes and prevents reuse from its first changed token.
|
||||
|
||||
### Loaded sessions
|
||||
|
||||
**What the model sees**: `session/load` resumes the persisted log, after which the loop sends its reconstructed history and request header. Replaying that log to the editor is not an extra model message.
|
||||
|
||||
**Token effect**: Restored context has the persistence and session packages' normal retained cost; ACP replay to the client adds none.
|
||||
|
||||
**KV Cache effect**: Loading does not rewrite the stored log, but the next request is reconstructed under the current envelope and route. Reuse requires that reconstruction to match; ACP replay to the client has no cache effect.
|
||||
|
||||
## Known Limitations and Deferred Work
|
||||
|
||||
- **`additionalDirectories`** — rejected. A session operates in its single `cwd` (see Per-session cwd); widening the tool/filesystem scope to extra roots is a separate sandbox concern, not yet implemented.
|
||||
|
||||
@@ -20,6 +20,8 @@ This package carries no loader hooks and no dev-mode surface: the `dsh-scripts`
|
||||
|
||||
Indirectly, through the plugin tree it loads, which determines the prompts, schemas, messages, and model adapter in the resulting application.
|
||||
|
||||
**KV Cache effect**: No direct invalidation; the named consumer owns any request-prefix changes.
|
||||
|
||||
## Known Limitations and Deferred Work
|
||||
|
||||
- **Bare package specifiers depend on Loader internals** — production bins need `node --expose-internals` or the Loader's optional native fallback; an in-process caller without either must use resolvable relative/file specifiers or tsx path mapping.
|
||||
|
||||
@@ -30,6 +30,8 @@ The plugin answers `shutdown`, disposes SDK-owned agents and subscriptions to qu
|
||||
|
||||
**Token effect**: Data-dependent user-message tokens enter retained session history and are resent on later turns until another package compacts them. The JSON-RPC frames, session notifications, and server bookkeeping add zero model-context tokens.
|
||||
|
||||
**KV Cache effect**: Append-only; newly visible content follows the reusable request prefix and does not invalidate existing KV-cache entries.
|
||||
|
||||
## Known Limitations and Deferred Work
|
||||
|
||||
- **The wire has no per-session close or prompt-cancel method** — SDK-created agents remain live until process shutdown, and one accepted prompt runs to agent idle before that session accepts another.
|
||||
|
||||
@@ -10,6 +10,8 @@ The service requires a confining `ctx.bash` executor and `ctx.approval`. A table
|
||||
|
||||
Indirectly, through `dsh-user-approval` and `dsh-tool-bash`, which render the approval-policy prompt, switch notice, and sandboxed tool outcomes selected by this service's knob events; `permission/preset` itself is log-only.
|
||||
|
||||
**KV Cache effect**: No direct invalidation; the named consumer owns any request-prefix changes.
|
||||
|
||||
## Known Limitations and Deferred Work
|
||||
|
||||
- **Only two mechanism knobs are bundled** — presets select sandbox mode and approval policy; an agent/profile choice is not part of `PresetSpec` yet.
|
||||
|
||||
@@ -29,12 +29,16 @@ The plugin seeds display labels from the live agent registry, then tracks `agent
|
||||
|
||||
**Token effect**: Submitted text is retained under the agent loop's normal session-history and compaction rules. The welcome banner, `> ` prompt, rendered transcript, and `[tool call]` / `[tool result]` terminal lines add no tokens.
|
||||
|
||||
**KV Cache effect**: Append-only; newly visible content follows the reusable request prefix and does not invalidate existing KV-cache entries.
|
||||
|
||||
### Terminal user-interaction answers
|
||||
|
||||
**What the model sees**: When a consumer calls `ctx.userInteraction.ask()`, this provider renders the question in the terminal and returns selected option labels or `custom` text. Through `dsh-tool-ask-user`, closed stdin becomes `Error: ask_user_question cannot be answered because stdin is closed`; disposal or abort becomes `Error: ask_user_question was interrupted before the user answered`.
|
||||
|
||||
**Token effect**: Waiting and terminal prompts add no tokens; the resolved answer or error is model-visible only through the calling tool or plugin's result.
|
||||
|
||||
**KV Cache effect**: Append-only; newly visible content follows the reusable request prefix and does not invalidate existing KV-cache entries.
|
||||
|
||||
## Known Limitations and Deferred Work
|
||||
|
||||
- **One configured session receives stdin** — the session/event renderer can print output from any session, but input lines always drive the configured `sessionId` rather than routing by the visible label.
|
||||
|
||||
@@ -27,12 +27,16 @@ This is the consumer package for the user-interaction seam. It does not render U
|
||||
|
||||
**Token effect**: Fixed schema cost on every request where the tool is visible.
|
||||
|
||||
**KV Cache effect**: Prefix-stable while the definition and visibility are unchanged. Plugin lifecycle or scoped restrictions may invalidate reuse from this schema.
|
||||
|
||||
### Tool-call history and result
|
||||
|
||||
**What the model sees**: The model's full questions remain in the assistant tool-call arguments. After the human answers, the next step sees compact JSON in the exact shape `{"answers":[{"id":"<id>","selected":["<label>"],"custom":"<text>"}]}`; `custom` is omitted when unused and `selected` can contain zero, one, or several labels. UI interaction while the call is pending is not model context.
|
||||
|
||||
**Token effect**: Arguments and answer JSON are data-dependent retained tokens; there is no token cost while waiting for the human.
|
||||
|
||||
**KV Cache effect**: Append-only; newly visible content follows the reusable request prefix and does not invalidate existing KV-cache entries.
|
||||
|
||||
## Known Limitations and Deferred Work
|
||||
|
||||
- **A pending question blocks the tool call until the human answers** — the tool declares no `timeout-policy` budget; cancellation rides the turn's `exec.signal` only.
|
||||
|
||||
@@ -51,12 +51,16 @@ The palette uses the standard 16-color ANSI foregrounds and SGR attributes, whic
|
||||
|
||||
**Token effect**: Submitted text is retained under the agent loop's normal session-history and compaction rules. Headers, cards, Markdown rendering, status lines, plans, and help text add no tokens.
|
||||
|
||||
**KV Cache effect**: Append-only; newly visible content follows the reusable request prefix and does not invalidate existing KV-cache entries.
|
||||
|
||||
### Interactive user-question answers
|
||||
|
||||
**What the model sees**: When a consumer calls `ctx.userInteraction.ask()`, this provider presents each question in order and returns selected option labels or `custom` text. Abort, cancellation, or UI disposal becomes `Error: ask_user_question was interrupted before the user answered` through `dsh-tool-ask-user`.
|
||||
|
||||
**Token effect**: Waiting and terminal overlays add no tokens; the resolved answer or error is model-visible only through the calling tool or plugin's result.
|
||||
|
||||
**KV Cache effect**: Append-only; newly visible content follows the reusable request prefix and does not invalidate existing KV-cache entries.
|
||||
|
||||
## Known Limitations and Deferred Work
|
||||
|
||||
- **One configured session owns the transcript and editor** — questions from other agents can still use the shared overlay provider, but session rendering and prompt input remain bound to `sessionId`.
|
||||
|
||||
@@ -18,6 +18,8 @@ The tools pipeline routes `ask` decisions through this seam and fails closed whe
|
||||
|
||||
**Token effect**: Small fixed per-request cost, larger under `never`; a change notice is conditional and retained in history.
|
||||
|
||||
**KV Cache effect**: Prefix-stable while the approval policy is unchanged. An `ask`/`never` switch changes the system-prompt section and invalidates reuse from its first changed token; the accompanying notice is append-only.
|
||||
|
||||
#### Ask-policy prompt section
|
||||
|
||||
```markdown
|
||||
@@ -37,6 +39,8 @@ Approval prompts are disabled in this session: actions that require approval are
|
||||
|
||||
**Token effect**: Zero duplicate audit tokens. A rejection may replace a normal tool result with a small retained error, while an allowance leaves the consumer's ordinary result.
|
||||
|
||||
**KV Cache effect**: Append-only; newly visible content follows the reusable request prefix and does not invalidate existing KV-cache entries.
|
||||
|
||||
## Known Limitations and Deferred Work
|
||||
|
||||
- **Requests are valid only inside an open turn** — an idle or between-turn caller throws before auditing; a durable out-of-turn approval workflow is deferred.
|
||||
|
||||
@@ -27,6 +27,8 @@ This is the interface package. Model-facing consumers such as `@deepseek-ai/dsh-
|
||||
|
||||
Indirectly, through `dsh-tool-ask-user`, which retains a successful provider answer as compact JSON or one of these failures: `Error: ask_user_question was aborted before the user answered`, `Error: ask_user_question requires at least one question`, `Error: no user-interaction provider is registered`, or `Error: <message>`. Waiting for the human adds no tokens.
|
||||
|
||||
**KV Cache effect**: No direct invalidation; the named consumer owns any request-prefix changes.
|
||||
|
||||
## Known Limitations and Deferred Work
|
||||
|
||||
- **One provider per context** — there is no routing or fan-out to multiple UIs; a second registration throws `DUPLICATE_PROVIDER`, and with none registered `ask()` throws `NO_PROVIDER` rather than degrading.
|
||||
|
||||
@@ -12,6 +12,8 @@ The resolver reads its inputs at call time. It does not cache a result, create t
|
||||
|
||||
Indirectly, through `dsh-tool-bash`, which exposes the resolved path to model bash as `DSH_HOME` without adding a prompt section.
|
||||
|
||||
**KV Cache effect**: No direct invalidation; the named consumer owns any request-prefix changes.
|
||||
|
||||
## Known Limitations and Deferred Work
|
||||
|
||||
- **Resolution only** — the resolver makes a path absolute but does not create it, check access, or canonicalize symlinks; each consumer owns those filesystem decisions.
|
||||
@@ -85,6 +85,8 @@ const footer = formatRetentionNotice(
|
||||
|
||||
Indirectly, through tool consumers that render retained content and omission metadata.
|
||||
|
||||
**KV Cache effect**: No direct invalidation; the named consumer owns any request-prefix changes.
|
||||
|
||||
## Known Limitations and Deferred Work
|
||||
|
||||
- **Item retention supports `head` only** — tail, head/tail, pagination, grouping, and provider-completeness semantics remain tool-owned.
|
||||
|
||||
@@ -52,6 +52,8 @@ Local file `read`/`write`/`edit` take no `timeoutMs`: a syscall is best-effort-a
|
||||
|
||||
Indirectly, through consumers such as `dsh-timeout-policy`, which may replace a provider result with a retained timeout error or suppress a late result.
|
||||
|
||||
**KV Cache effect**: No direct invalidation; the named consumer owns any request-prefix changes.
|
||||
|
||||
## Known Limitations and Deferred Work
|
||||
|
||||
- **Notification only** — a deadline cannot stop work that ignores its signal; every capability still needs its own socket/process/task termination path.
|
||||
|
||||
@@ -44,6 +44,8 @@ The tool never calls a provider's `available()` and never enumerates providers
|
||||
|
||||
**Token effect**: Fixed guidance cost per request for each config-enabled tool, even when a restriction hides its schema.
|
||||
|
||||
**KV Cache effect**: Prefix-stable while enabled tools, scope, and guidance text are unchanged. Config enablement or plugin lifecycle may invalidate reuse from the first changed prompt section; scoped schema restrictions do not remove it.
|
||||
|
||||
#### Web search guidance
|
||||
|
||||
```markdown
|
||||
@@ -62,24 +64,32 @@ Use the web_fetch tool to retrieve the content of a specific HTTP(S) URL (for ex
|
||||
|
||||
**Token effect**: Fixed schema cost per request; config disablement removes both schema and guidance, while a scoped restriction removes only the schema.
|
||||
|
||||
**KV Cache effect**: Prefix-stable while definitions and visibility are unchanged. Config enablement, plugin lifecycle, or scoped restrictions may invalidate reuse from the first changed schema token.
|
||||
|
||||
### Search result
|
||||
|
||||
**What the model sees**: The optional provider-owned answer is followed by `Sources:` and data-dependent lines shaped exactly `- [<title-or-url>](<url>)`, optionally suffixed ` — <snippet> (<publishedAt>)`. With neither answer nor sources the result says `No results found.` A capped list adds `(Showing the first <count> sources. Refine the query for more.)`; every result ends `Cite the relevant URLs above as markdown links in your answer.`
|
||||
|
||||
**Token effect**: Data-dependent results are resent until compaction and sources are capped by `searchMaxResults`.
|
||||
|
||||
**KV Cache effect**: Append-only; newly visible content follows the reusable request prefix and does not invalidate existing KV-cache entries.
|
||||
|
||||
### Fetch result
|
||||
|
||||
**What the model sees**: A successful fetch is exactly `Fetched <finalUrl> (HTTP <statusCode>)`, a blank line, and the provider-owned decoded body. Truncation adds a blank line and `(Content truncated. Fetch a more specific URL or section for the full text.)`; failures become `Error: <message>`. Queries and URLs remain in call history.
|
||||
|
||||
**Token effect**: Provider caps bound body size; retained call arguments and results are resent until compaction, and timeout policy can replace a late result with a short error.
|
||||
|
||||
**KV Cache effect**: Append-only; newly visible content follows the reusable request prefix and does not invalidate existing KV-cache entries.
|
||||
|
||||
### Argument errors
|
||||
|
||||
**What the model sees**: Blank inputs become exactly `Error: query must be a non-empty string` or `Error: url must be a non-empty string`.
|
||||
|
||||
**Token effect**: Only the failing call adds these retained tokens.
|
||||
|
||||
**KV Cache effect**: Append-only; newly visible content follows the reusable request prefix and does not invalidate existing KV-cache entries.
|
||||
|
||||
## Known Limitations and Deferred Work
|
||||
|
||||
- **`htmlToMarkdown` is a minimal regex converter, not an HTML parser** — it strips script/style/noscript, keeps headings/bullets/links, and decodes about a dozen named entities; tables, images, and nested formatting are lost.
|
||||
|
||||
@@ -38,6 +38,8 @@ The numeric limits are validated at plugin construction: every cap except `maxRe
|
||||
|
||||
Indirectly, through [`dsh-tool-web`](../tool-web/README.md), which places this provider's `maxBodyChars`-bounded decoded text or markdown-shaped HTML under its fetch-result wrapper and retains provider failures while redirects, headers, and transport mechanics remain hidden.
|
||||
|
||||
**KV Cache effect**: No direct invalidation; the named consumer owns any request-prefix changes.
|
||||
|
||||
## Known Limitations and Deferred Work
|
||||
|
||||
- **SSRF / private-network protection is deferred** — no blocking of private, loopback, link-local, multicast, or otherwise non-public destinations, no DNS-resolve-then-validate, no per-hop re-validation (see [the web capability seam RFC](../../../docs/rfc/implemented/architecture/2026-06-24-web-capability-seam.md)). Until it lands, this provider is an SSRF primitive and **must not be enabled** in a deployment that can reach sensitive internal network targets.
|
||||
|
||||
@@ -47,12 +47,16 @@ Provider failures become `WEB_PROVIDER_ERROR`; caller cancellation becomes `WEB_
|
||||
|
||||
**Token effect**: Separate provider input and output tokens are incurred for each search; `maxTokens` caps generated output and `maxUses` caps native search uses.
|
||||
|
||||
**KV Cache effect**: Independent of the conversation request cache. The auxiliary instruction and native tool definition can form a stable prefix, but each changed query or model route prevents reuse from its first difference.
|
||||
|
||||
### Conversation tool result, indirectly
|
||||
|
||||
**What the model sees**: Through [`dsh-tool-web`](../tool-web/README.md), the conversation model sees deduplicated URLs, titles, dates, and citation snippets from structured search blocks; provider prose is not trusted as an answer. This provider's exact failures are `DeepSeek search aborted`, `DeepSeek search request failed: <error>`, `DeepSeek returned no web_search_tool_result blocks; the request may not have triggered native web search`, and `DeepSeek returned an unprocessable response body: <error>`; HTTP failures preserve the provider message. The consumer owns the error wrapper.
|
||||
|
||||
**Token effect**: Zero direct conversation tokens from registration. Result tokens scale with returned sources and snippets, then the seam enforces the requested source bound.
|
||||
|
||||
**KV Cache effect**: Append-only; newly visible content follows the reusable request prefix and does not invalidate existing KV-cache entries.
|
||||
|
||||
## Known Limitations and Deferred Work
|
||||
|
||||
- **One search costs a full Messages model turn** — latency plus generated tokens, with up to `maxUses` server-side searches; DeepSeek exposes no dedicated retrieval endpoint.
|
||||
|
||||
@@ -29,6 +29,8 @@ Exa returns a flat `results[]` and no generated answer, so `content` is omitted.
|
||||
|
||||
Indirectly, through [`dsh-tool-web`](../tool-web/README.md), which retains this provider's `maxResults`-bounded URLs, titles, first highlights, and publication dates or its exact `Exa search aborted`, `Exa search request failed: <error>`, and `Exa returned an unprocessable response body: <error>` failures under the consumer's error wrapper while generated answers and provider-private fields remain outside context.
|
||||
|
||||
**KV Cache effect**: No direct invalidation; the named consumer owns any request-prefix changes.
|
||||
|
||||
## Known Limitations and Deferred Work
|
||||
|
||||
- **A result with no non-blank highlight is dropped entirely** — no portable snippet to map, so fewer sources than the requested count can return.
|
||||
|
||||
@@ -33,12 +33,16 @@ This is an **implementation** package: it registers a provider into `ctx.web`, i
|
||||
|
||||
**Token effect**: Separate provider tokens are incurred per search; `maxTokens` caps the generated answer.
|
||||
|
||||
**KV Cache effect**: Independent of the conversation request cache. An identical query under the same model route may reuse provider cache; a changed query or route establishes a different prefix.
|
||||
|
||||
### Conversation tool result, indirectly
|
||||
|
||||
**What the model sees**: Through [`dsh-tool-web`](../tool-web/README.md), the conversation model sees the generated answer plus structured result metadata or URL-only citations. This provider's exact failures are `Perplexity search aborted`, `Perplexity search request failed: <error>`, and `Perplexity returned an unprocessable response body: <error>`; HTTP failures preserve the provider message. The consumer owns the error wrapper.
|
||||
|
||||
**Token effect**: Zero direct conversation tokens from registration. Answer and source tokens are data-dependent, source count is seam-bounded, and the retained result or error is resent until compaction.
|
||||
|
||||
**KV Cache effect**: Append-only; newly visible content follows the reusable request prefix and does not invalidate existing KV-cache entries.
|
||||
|
||||
## Known Limitations and Deferred Work
|
||||
|
||||
- **Citation-fallback sources are URL-only** — when Perplexity omits structured `search_results[]`, sources carry no `title`/`snippet`/`publishedAt`, so the tool renders bare hostname labels.
|
||||
|
||||
@@ -47,6 +47,8 @@ The failure branches throw `WebError`, whose structured code (plus message detai
|
||||
|
||||
Indirectly, through `dsh-tool-web`, which retains bounded normalized provider data or the exact configured-provider, unavailable-provider, no-provider, multiple-provider, and `Error: <message>` failures while this registry contributes no prompt or schema itself.
|
||||
|
||||
**KV Cache effect**: No direct invalidation; the named consumer owns any request-prefix changes.
|
||||
|
||||
## Known Limitations and Deferred Work
|
||||
|
||||
- **No observation surface** — no provider-change event and no capability-status query; availability is observed only by executing `search()`/`fetch()` and routing the thrown `WebError` codes, and the no-provider failure is the generic `WEB_PROVIDER_UNAVAILABLE` with no per-provider reason enumeration ([RFC](../../../docs/rfc/implemented/simplification/2026-07-04-drop-unconsumed-web-observation-surface.md)).
|
||||
|
||||
@@ -29,6 +29,8 @@ Decided up front (per the [render-intent RFC](../../../docs/rfc/implemented/arch
|
||||
|
||||
**Token effect**: Small fixed guidance cost per request while the plugin is active.
|
||||
|
||||
**KV Cache effect**: Prefix-stable while the plugin scope and guidance text are unchanged. Activation or disposal may invalidate reuse from this prompt section.
|
||||
|
||||
#### Workflow guidance
|
||||
|
||||
```markdown
|
||||
@@ -41,12 +43,16 @@ Use the <toolName> tool ONLY when the user explicitly asks for a workflow or for
|
||||
|
||||
**Token effect**: Substantial fixed schema cost on each request where the tool is visible.
|
||||
|
||||
**KV Cache effect**: Prefix-stable while `toolName`, definition, and visibility are unchanged. Renaming, plugin lifecycle, or scoped restrictions may invalidate reuse from this schema.
|
||||
|
||||
### Tool-call history and result
|
||||
|
||||
**What the model sees**: The full model-written script, metadata, and args remain in the assistant tool call. Success is exactly `workflow "<name>" completed (<count> agent<optional-s>).`, newline, `Return value:`, newline, and pretty-printed data-dependent JSON; a cap adds `… [truncated: <omitted> more characters]` on a new line. Failures are exactly `Error: workflow run was cancelled`, optionally suffixed ` (<error>)`, `Error: workflow run failed: <error-or-unknown error>`, or defensively `Error: workflow run ended abnormally (<reason>)`; a call without an owning agent becomes `Error: workflow tool requires a calling agent (exec.agent was undefined)`. Intermediate child messages are omitted.
|
||||
|
||||
**Token effect**: Call tokens can be large and remain until compaction. Result rendering is capped by `maxResultChars`; child-model tokens are separate from the parent's retained context.
|
||||
|
||||
**KV Cache effect**: Append-only; newly visible content follows the reusable request prefix and does not invalidate existing KV-cache entries.
|
||||
|
||||
## Known Limitations and Deferred Work
|
||||
|
||||
- **The parent turn blocks until the whole workflow settles** — there is no background start/poll surface, and cancellation discards partial output as an error.
|
||||
|
||||
@@ -89,12 +89,16 @@ The host keeps a ledger of forwarded child starts. A graceful worker supplies th
|
||||
|
||||
**Token effect**: Potentially many independent child contexts are paid, bounded by `maxConcurrentAgents`, `maxTotalAgents`, and `maxItemsPerCall`; they never join the parent history directly.
|
||||
|
||||
**KV Cache effect**: Independent of the parent request cache and of sibling children. Each child can reuse only a byte-identical prefix under its own provider, model, prompt, and schema; its later history grows append-only.
|
||||
|
||||
### Parent tool result, indirectly
|
||||
|
||||
**What the model sees**: Through [`dsh-tool-workflow`](../tool-workflow/README.md), success exposes only the materialized final JSON value and child count in that consumer's wrapper. This engine supplies stable errors including `workflow script does not parse: <error>`, `invalid meta: <violations>`, `agent() requires a non-empty prompt string`, `agent() could not start a child: <error>`, `child agent run failed: <error>`, and its exact `parallel()`, `pipeline()`, `phase()`, option, schema, and JSON-boundary validation messages. Intermediate child outputs are available to the script but not the parent model.
|
||||
|
||||
**Token effect**: Zero direct parent tokens from this engine. Final result size is capped by the tool consumer and retained until compaction.
|
||||
|
||||
**KV Cache effect**: Append-only; newly visible content follows the reusable request prefix and does not invalidate existing KV-cache entries.
|
||||
|
||||
## Known Limitations and Deferred Work
|
||||
|
||||
- **The worker/vm is not a security boundary** — model-written code can escape `node:vm` and reach the worker's process authority; a hostile-code deployment needs a separate-process or container engine.
|
||||
|
||||
@@ -42,6 +42,8 @@ A child that resolves normally with a non-completed stop reason is not an infras
|
||||
|
||||
Indirectly, through `dsh-tool-workflow` and a workflow engine, which create child-agent requests and return a retained parent tool result.
|
||||
|
||||
**KV Cache effect**: No direct invalidation; the named consumer owns any request-prefix changes.
|
||||
|
||||
## Known Limitations and Deferred Work
|
||||
|
||||
- **Foreground collection only** — the caller owns one live run and awaits it; background start/poll, spill handles, and detached collection are deferred.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
* Doc-sync gate for package README Model Experience sections. It validates
|
||||
* audited package classifications, context-surface fields, package-owned text
|
||||
* blocks, generated-catalog links, and final-section order. See the
|
||||
* audited package classifications, model/token/KV-cache fields, package-owned
|
||||
* text blocks, generated-catalog links, and final-section order. See the
|
||||
* [Model Experience RFC](../docs/rfc/implemented/process/2026-07-12-package-model-experience-contract.md).
|
||||
*/
|
||||
|
||||
@@ -14,6 +14,7 @@ const HEADING = '## Model Experience'
|
||||
const LIMITATIONS_HEADING = '## Known Limitations and Deferred Work'
|
||||
const MODEL_VIEW_LABEL = '**What the model sees**'
|
||||
const TOKEN_EFFECT_LABEL = '**Token effect**'
|
||||
const KV_CACHE_EFFECT_LABEL = '**KV Cache effect**'
|
||||
|
||||
type SentenceKind = 'none' | 'indirect'
|
||||
|
||||
@@ -34,9 +35,9 @@ const NO_MODEL_EXPERIENCE_SECTION: Readonly<Record<string, string>> = {
|
||||
}
|
||||
|
||||
/**
|
||||
* Packages whose Model Experience is simple enough for one gated sentence.
|
||||
* Every other package must carry canonical context-surface blocks. A package
|
||||
* moves on or off this list with the change to its context behavior.
|
||||
* Packages whose Model Experience is simple enough for one gated sentence plus
|
||||
* a KV-cache field. Every other package must carry canonical context-surface
|
||||
* blocks. A package moves on or off this list with its context behavior.
|
||||
*/
|
||||
const SENTENCE_MODEL_EXPERIENCE: Readonly<Record<string, SentenceContract>> = {
|
||||
'packages/bash/bash': { kind: 'indirect', reason: 'The service interface delegates all model rendering to dsh-tool-bash.' },
|
||||
@@ -91,6 +92,7 @@ interface ContextSurface {
|
||||
heading: Line
|
||||
modelView: Line
|
||||
tokenEffect: Line
|
||||
kvCacheEffect: Line
|
||||
title: string
|
||||
verbatimBlocks: number
|
||||
}
|
||||
@@ -107,7 +109,7 @@ function validateNestedVerbatim(raw: readonly string[]): { blocks: number; error
|
||||
while (raw[cursor]?.trim().length === 0) cursor += 1
|
||||
if (cursor === raw.length) break
|
||||
if (!/^#### \S/.test(raw[cursor] ?? '')) {
|
||||
return { blocks, error: 'content after Token effect must be a titled H4 verbatim block' }
|
||||
return { blocks, error: 'content after KV Cache effect must be a titled H4 verbatim block' }
|
||||
}
|
||||
const title = (raw[cursor] as string).slice('#### '.length)
|
||||
const fragment = headingFragment(title)
|
||||
@@ -165,6 +167,7 @@ let indirectCount = 0
|
||||
let verbatimBlockCount = 0
|
||||
let systemPromptSurfaceCount = 0
|
||||
let toolSchemaSurfaceCount = 0
|
||||
let kvCacheEffectCount = 0
|
||||
|
||||
for (const [pkg, reason] of Object.entries(NO_MODEL_EXPERIENCE_SECTION)) {
|
||||
if (!scannedPackages.has(pkg)) {
|
||||
@@ -258,13 +261,24 @@ for (const packageJson of packageJsons) {
|
||||
if (sentenceContract !== undefined) {
|
||||
const pattern = sentenceContract.kind === 'none' ? /^None, as .+\.$/ : /^Indirectly, through .+\.$/
|
||||
const rawContent = rawSection.filter(line => line.trim().length > 0)
|
||||
if (content.length !== 1 || rawContent.length !== 1 || !pattern.test(content[0]?.raw ?? '')) {
|
||||
const sentence = content[0]
|
||||
const kvCacheEffect = content[1]
|
||||
if (content.length !== 2 || rawContent.length !== 2 || !pattern.test(sentence?.raw ?? '')) {
|
||||
const prefix = sentenceContract.kind === 'none' ? 'None, as ' : 'Indirectly, through '
|
||||
failures.push({ path: readme, message: `must contain exactly one sentence beginning ${JSON.stringify(prefix)} and ending with a period` })
|
||||
failures.push({ path: readme, message: `must contain exactly one sentence beginning ${JSON.stringify(prefix)} and ending with a period, followed by ${KV_CACHE_EFFECT_LABEL}` })
|
||||
continue
|
||||
}
|
||||
if (kvCacheEffect === undefined || !kvCacheEffect.raw.startsWith(`${KV_CACHE_EFFECT_LABEL}: `) || kvCacheEffect.raw.slice(`${KV_CACHE_EFFECT_LABEL}: `.length).trim().length === 0) {
|
||||
failures.push({ path: readme, message: `line ${kvCacheEffect?.index ?? sentence?.index ?? modelHeading.index}: short Model Experience form requires non-empty ${KV_CACHE_EFFECT_LABEL}: text` })
|
||||
continue
|
||||
}
|
||||
if (sentence === undefined || sentence.index !== modelHeading.index + 2 || kvCacheEffect.index !== sentence.index + 2) {
|
||||
failures.push({ path: readme, message: 'short Model Experience sentence and KV-cache field require one blank line between each element' })
|
||||
continue
|
||||
}
|
||||
if (sentenceContract.kind === 'none') explainedNoneCount += 1
|
||||
else indirectCount += 1
|
||||
kvCacheEffectCount += 1
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -292,6 +306,7 @@ for (const packageJson of packageJsons) {
|
||||
const heading = entries[0] as Line
|
||||
const modelView = entries[1]
|
||||
const tokenEffect = entries[2]
|
||||
const kvCacheEffect = entries[3]
|
||||
const title = heading.raw.slice('### '.length)
|
||||
const fragment = headingFragment(title)
|
||||
if (fragment.length === 0) {
|
||||
@@ -314,39 +329,45 @@ for (const packageJson of packageJsons) {
|
||||
surfaceError = true
|
||||
break
|
||||
}
|
||||
if (kvCacheEffect === undefined || !kvCacheEffect.raw.startsWith(`${KV_CACHE_EFFECT_LABEL}: `) || kvCacheEffect.raw.slice(`${KV_CACHE_EFFECT_LABEL}: `.length).trim().length === 0) {
|
||||
failures.push({ path: readme, message: `line ${kvCacheEffect?.index ?? heading.index}: context surface requires non-empty ${KV_CACHE_EFFECT_LABEL}: text` })
|
||||
surfaceError = true
|
||||
break
|
||||
}
|
||||
if ((surfaceIndex === 0 && heading.index !== modelHeading.index + 2)
|
||||
|| rawLines[heading.index - 2]?.trim().length !== 0
|
||||
|| modelView.index !== heading.index + 2
|
||||
|| tokenEffect.index !== modelView.index + 2) {
|
||||
|| tokenEffect.index !== modelView.index + 2
|
||||
|| kvCacheEffect.index !== tokenEffect.index + 2) {
|
||||
failures.push({ path: readme, message: `line ${heading.index}: context-surface heading and fields require one blank line between each element` })
|
||||
surfaceError = true
|
||||
break
|
||||
}
|
||||
const unexpected = entries.slice(3).find(line => !/^#### \S/.test(line.raw))
|
||||
const unexpected = entries.slice(4).find(line => !/^#### \S/.test(line.raw))
|
||||
if (unexpected !== undefined) {
|
||||
failures.push({ path: readme, message: `line ${unexpected.index}: content after ${TOKEN_EFFECT_LABEL} must be a titled H4 plus \`markdown\` fence inside this context surface` })
|
||||
failures.push({ path: readme, message: `line ${unexpected.index}: content after ${KV_CACHE_EFFECT_LABEL} must be a titled H4 plus \`markdown\` fence inside this context surface` })
|
||||
surfaceError = true
|
||||
break
|
||||
}
|
||||
const nextHeadingLine = surfaceStarts[surfaceIndex + 1]?.line.index ?? nextH2Line
|
||||
const verbatim = validateNestedVerbatim(rawLines.slice(tokenEffect.index, nextHeadingLine - 1))
|
||||
const verbatim = validateNestedVerbatim(rawLines.slice(kvCacheEffect.index, nextHeadingLine - 1))
|
||||
if (verbatim.error !== undefined) {
|
||||
failures.push({ path: readme, message: `line ${tokenEffect.index}: ${verbatim.error}` })
|
||||
failures.push({ path: readme, message: `line ${kvCacheEffect.index}: ${verbatim.error}` })
|
||||
surfaceError = true
|
||||
break
|
||||
}
|
||||
if (entries.length - 3 !== verbatim.blocks) {
|
||||
failures.push({ path: readme, message: `line ${tokenEffect.index}: every nested H4 must own exactly one \`markdown\` fence` })
|
||||
if (entries.length - 4 !== verbatim.blocks) {
|
||||
failures.push({ path: readme, message: `line ${kvCacheEffect.index}: every nested H4 must own exactly one \`markdown\` fence` })
|
||||
surfaceError = true
|
||||
break
|
||||
}
|
||||
if (/\]\(#[^)]+\)/.test(modelView.raw) || /\]\(#[^)]+\)/.test(tokenEffect.raw)) {
|
||||
if (/\]\(#[^)]+\)/.test(modelView.raw) || /\]\(#[^)]+\)/.test(tokenEffect.raw) || /\]\(#[^)]+\)/.test(kvCacheEffect.raw)) {
|
||||
failures.push({ path: readme, message: `line ${heading.index}: Model Experience fields must not link between local subsections; nest the H4 in its owning H3` })
|
||||
surfaceError = true
|
||||
break
|
||||
}
|
||||
surfaceFragments.add(fragment)
|
||||
surfaces.push({ heading, modelView, tokenEffect, title, verbatimBlocks: verbatim.blocks })
|
||||
surfaces.push({ heading, modelView, tokenEffect, kvCacheEffect, title, verbatimBlocks: verbatim.blocks })
|
||||
}
|
||||
if (surfaceError) continue
|
||||
|
||||
@@ -385,11 +406,12 @@ for (const packageJson of packageJsons) {
|
||||
contextSurfaceCount += surfaces.length
|
||||
systemPromptSurfaceCount += surfaces.filter(surface => isDirectSystemPromptSurface(surface.title)).length
|
||||
toolSchemaSurfaceCount += surfaces.filter(surface => /\bschemas?\b/i.test(surface.title)).length
|
||||
kvCacheEffectCount += surfaces.length
|
||||
structuredCount += 1
|
||||
}
|
||||
|
||||
if (failures.length === 0) {
|
||||
console.log(`verify-package-readme-model-experience: ${packageJsons.length} README(s) checked (${omittedSectionCount} audited omissions, ${structuredCount} structured, ${contextSurfaceCount} context surfaces, ${systemPromptSurfaceCount} fenced system-prompt surfaces, ${toolSchemaSurfaceCount} catalog-linked tool-schema surfaces, ${explainedNoneCount} explained none, ${indirectCount} indirect, ${verbatimBlockCount} verbatim markdown blocks), all conform.`)
|
||||
console.log(`verify-package-readme-model-experience: ${packageJsons.length} README(s) checked (${omittedSectionCount} audited omissions, ${structuredCount} structured, ${contextSurfaceCount} context surfaces, ${kvCacheEffectCount} KV-cache fields, ${systemPromptSurfaceCount} fenced system-prompt surfaces, ${toolSchemaSurfaceCount} catalog-linked tool-schema surfaces, ${explainedNoneCount} explained none, ${indirectCount} indirect, ${verbatimBlockCount} verbatim markdown blocks), all conform.`)
|
||||
process.exit(0)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user