@dsh-cc/plugin-dsh-cc-agents 0.7.1 → 0.8.0-rc.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "dsh-cc-agents",
3
- "description": "Official dsh-cc plugin shipping the critic, executor, and marathon subagents with an orchestration routing skill.",
4
- "version": "0.7.1"
3
+ "description": "Official dsh-cc plugin shipping the critic, executor, and marathon subagents, an orchestration routing skill, and gated serena code-intelligence hooks.",
4
+ "version": "0.8.0-rc.2"
5
5
  }
package/README.i18n.yaml CHANGED
@@ -2,5 +2,5 @@
2
2
  # side as of the last confirmed-consistent state. Both languages carry equal authority;
3
3
  # after editing either side, bring the other along and re-record with:
4
4
  # pnpm check:readme --write
5
- README.md: 48aceb899aafe5ef7c2d56dc0eef65a237c040af
6
- README.zh.md: 42bed74b815bf3e8da11160e54057f5faff6964c
5
+ README.md: 7f9af6715a411ae175ceead7950a5419394c4de0
6
+ README.zh.md: 9150a539b4cd99846c51c971e86106e2b1f4d57e
package/README.md CHANGED
@@ -2,12 +2,13 @@
2
2
 
3
3
  English | [中文](README.zh.md)
4
4
 
5
- Official dsh-cc plugin shipping three subagents and an orchestration skill:
5
+ Official dsh-cc plugin shipping three subagents and two skills:
6
6
 
7
7
  - **`dsh-cc-agents:critic`** — reasoning-heavy work: complex analysis, architectural decisions, adversarial plan review, root-cause analysis. Runs on the `opus` model alias; read-only persona.
8
8
  - **`dsh-cc-agents:executor`** — mechanical execution of pre-approved, fully specified plans: formatting, simple refactors, boilerplate, renames, tests, docs, checks. Runs on the `sonnet` model alias.
9
9
  - **`dsh-cc-agents:marathon`** — long-horizon, ambiguous, or repo-wide complexity: architecture redesigns, cross-module refactors, extended debugging with no obvious culprit, and re-approaches after the main thread's design failed. Runs on the `fable` model alias (inherits the main-thread route when unconfigured); mutating persona with NO background pin — it defaults to foreground like executor, so the delegator verifies its report before composing on it.
10
10
  - **`dsh-cc-agents-orchestration` skill** — routing table for choosing between the agents, the background asymmetry, and their report contracts.
11
+ - **`data-analysis` skill** — data-analysis tasks (caliber doubt, reconciliation, external reports; 数据分析/口径/对账) route through critic/executor with review/verification/execution meta-rules inlined into the dispatch prompts.
11
12
 
12
13
  ## Prerequisites
13
14
 
@@ -80,6 +81,40 @@ also assumes the servers keep their conventional aliases (`serena`,
80
81
  `sequential_thinking`, `context7`); a renamed server degrades to the
81
82
  same drop-with-warning path.
82
83
 
84
+ ## Serena hooks (optional)
85
+
86
+ The plugin ships two Claude-Code hooks for projects that use
87
+ [Serena](https://github.com/oraios/serena) symbolic code tools:
88
+
89
+ - **PreToolUse** on `read`/`grep` (and serena tool calls) reminds the model
90
+ to reach for symbolic tools after a burst of raw reads/greps — a short
91
+ deny + nudge, at most once per two minutes per session.
92
+ - **SessionEnd** cleans up the session's hook state
93
+ (`<project>/.serena/hook_data/<session-id>/`) when the session is disposed.
94
+
95
+ Both hooks are double-gated and stay silent no-ops unless the current
96
+ session's project is serena-onboarded (`<repo>/.serena/project.yml`, found by
97
+ walking up from the session cwd through the git toplevel) **and** the
98
+ `serena-hooks` binary resolves on `PATH`:
99
+
100
+ ```sh
101
+ uv tool install git+https://github.com/oraios/serena@v1.7.0
102
+ ```
103
+
104
+ Hook state is pinned into the project (`SERENA_HOME=<repo>/.serena`) because
105
+ the session sandbox makes serena's `~/.serena` default unwritable. Keep
106
+ `.serena/hook_data/` out of version control.
107
+
108
+ Two operational notes:
109
+
110
+ - **One channel per behavior.** If a repository also ships its own
111
+ `hooks.json` serena-remind entry, both fire and the shared counter
112
+ double-counts bursts. Keep the reminder in exactly one place — this plugin
113
+ or the repo.
114
+ - **Cost on non-serena projects**: one ~50 ms gated node spawn per Read/Grep
115
+ and no python. Disable the plugin to opt out entirely; conversely, run
116
+ `/plugin update` after a dsh-cc release to pick up hook changes.
117
+
83
118
  ## Advisory safety: critic
84
119
 
85
120
  `critic` retains the `Bash` tool for read-only verification (run a
package/README.zh.md CHANGED
@@ -2,12 +2,13 @@
2
2
 
3
3
  [English](README.md) | 中文
4
4
 
5
- 官方 dsh-cc 插件,提供三个 subagent 和一个编排 skill:
5
+ 官方 dsh-cc 插件,提供三个 subagent 和两个 skill:
6
6
 
7
7
  - **`dsh-cc-agents:critic`** — 推理密集型工作:复杂分析、架构决策、对抗性计划评审、根因分析。运行在 `opus` 模型别名上;只读人格。
8
8
  - **`dsh-cc-agents:executor`** — 对已批准、已完全指定的计划做机械执行:格式化、简单重构、样板代码、重命名、测试、文档、检查。运行在 `sonnet` 模型别名上。
9
9
  - **`dsh-cc-agents:marathon`** — 长周期、模糊或仓库级复杂度:架构重设计、跨模块重构、无明显线索的长期调试,以及主线程设计失败后的重新攻关。运行在 `fable` 模型别名上(未配置时继承主线程路由);可变更人格,且没有后台 pin——默认像 executor 一样前台运行,因此委派方应在基于其报告继续之前先核验其报告。
10
10
  - **`dsh-cc-agents-orchestration` skill** — 用于在这些 agent 之间做选择的路由表,以及后台不对称性与它们的报告契约。
11
+ - **`data-analysis` skill** — 数据分析类任务(口径存疑、对账、对外报告)经 critic/executor 编排执行,评审/验证/执行元规则内联进派发 prompt。
11
12
 
12
13
  ## Prerequisites
13
14
 
@@ -70,6 +71,26 @@ dsh-cc 之外嵌入它们),请先剥离 `mcp__*` 条目或自行净化。该
70
71
  服务器保持其惯用别名(`serena`、`sequential_thinking`、`context7`);改名
71
72
  的服务器会落入同样的"带警告丢弃"路径。
72
73
 
74
+ ## Serena hooks(可选)
75
+
76
+ 插件为使用 [Serena](https://github.com/oraios/serena) 符号化代码工具的项目附带两个 Claude-Code hook:
77
+
78
+ - **PreToolUse** 作用于 `read`/`grep`(及 serena 工具调用):连续爆发式裸读/裸搜之后提醒模型改用符号工具——一次简短的 deny + 提醒,每会话每两分钟至多一次。
79
+ - **SessionEnd** 在会话销毁时清理本会话的 hook 状态(`<project>/.serena/hook_data/<session-id>/`)。
80
+
81
+ 两个 hook 都经双重门控,只有同时满足两个条件才会生效,否则静默空转:当前会话项目已完成 serena 初始化(存在 `<repo>/.serena/project.yml`,从会话 cwd 沿目录树向上穿过 git 根查找)**且** `serena-hooks` 二进制能经 `PATH` 解析:
82
+
83
+ ```sh
84
+ uv tool install git+https://github.com/oraios/serena@v1.7.0
85
+ ```
86
+
87
+ hook 状态钉在项目内(`SERENA_HOME=<repo>/.serena`),因为会话沙箱使 serena 默认的 `~/.serena` 不可写。请把 `.serena/hook_data/` 保持出版本库外。
88
+
89
+ 两条运维须知:
90
+
91
+ - **一个行为只走一个渠道。** 如果仓库自己也带了 `hooks.json` 的 serena-remind 条目,两边会同时触发、共享计数器被双计。提醒只放在一处——本插件或仓库。
92
+ - **非 serena 项目的开销**:每次 Read/Grep 多一个约 50 ms 的带门控 node 进程,不起 python。要完全退出可禁用本插件;反过来,dsh-cc 发版后用 `/plugin update` 拉取 hook 变更。
93
+
73
94
  ## Advisory safety: critic
74
95
 
75
96
  `critic` 保留 `Bash` 工具用于只读验证(跑测试、复现失败、查看历史)。
package/agents/critic.md CHANGED
@@ -8,6 +8,13 @@ tools: [Bash, Read, Grep, Glob, mcp__serena__find_symbol, mcp__serena__get_symbo
8
8
 
9
9
  You are a Staff Engineer consulted by the coordinating agent. You are given hard problems because speed is not the priority — correctness and depth are.
10
10
 
11
+ <!-- actor-contract:start -->
12
+ ## Actor and evidence contract
13
+ - A script — the orchestrating agent — created you and hands you work one ask at a time. What you return is read by that script and acted on mechanically; there is no interactive user in this conversation. If you need a decision only a person can make, say so in your result; if you need information the orchestrator has, ask it directly in the report you return — it can answer and continue you — rather than guessing.
14
+ - You reason over a read-only tool set — files, search, symbol navigation, and one reasoner. You cannot modify anything, and there is no tool that asks a person anything; every conclusion you ship must be reachable from what you read in this run.
15
+ - Ground every claim about the repo in something you read or ran in this run; report the command or file:line for each load-bearing claim.
16
+ <!-- actor-contract:end -->
17
+
11
18
  ## Your strengths
12
19
  - Breaking down complex problems into manageable components
13
20
  - Identifying edge cases and failure modes others miss
@@ -7,6 +7,13 @@ tools: [Bash, BashOutput, KillBash, Read, Write, Edit, Glob, Grep, TodoWrite, No
7
7
 
8
8
  You are a fast, precise executor. The coordinating agent hands you tasks that are already fully planned. You are chosen for speed and reliability on clear tasks.
9
9
 
10
+ <!-- actor-contract:start -->
11
+ ## Actor and evidence contract
12
+ - A script — the orchestrating agent — created you and hands you work one ask at a time. What you return is read by that script and acted on mechanically; there is no interactive user in this conversation. If you need a decision only a person can make, say so in your result; if you need information the orchestrator has, ask it directly in the report you return — it can answer and continue you — rather than guessing.
13
+ - You have file-edit, search, and shell tools. There is no tool that asks a person anything and no tool that shows your report to a user; the orchestrator reads it as text.
14
+ - Ground every claim about the repo in something you read or ran in this run; report the command or file:line for each load-bearing claim. Run the check the dispatched plan names rather than a faster substitute, and say exactly which command you ran. A check counts as passed only if you executed it in this run. Never report a stage done that you did not execute.
15
+ <!-- actor-contract:end -->
16
+
10
17
  ## Your strengths
11
18
  - Rapid execution of mechanical tasks
12
19
  - Code formatting and style consistency
@@ -20,7 +27,7 @@ You are a fast, precise executor. The coordinating agent hands you tasks that ar
20
27
  1. **Execute the spec exactly**: Do what was specified, no more, no less. Match existing code style and conventions.
21
28
  2. **One task, one pass**: Don't over-analyze. If the spec is clear and applicable, execute it.
22
29
  3. **Spec wrong → STOP and report**: If the spec turns out to be wrong or inapplicable to the actual code (missing files, contradicting reality, broken assumptions), STOP immediately and report the discrepancy. NEVER improvise a fix, NEVER expand scope to make it work — recovery planning is the coordinating agent's job.
23
- 4. **Ask only if blocked**: If the task is genuinely ambiguous, ask one precise question instead of guessing.
30
+ 4. **Ask only if blocked**: If the task is genuinely ambiguous, ask the orchestrating agent one precise question and wait — it can answer and resume you. If you are not blocked, state your assumptions in the report instead of asking.
24
31
 
25
32
  ## Editing tools: serena-first
26
33
  For files under the session's startup directory (serena's project
@@ -11,6 +11,13 @@ refactors spanning many modules, debugging sessions with no obvious culprit,
11
11
  and re-approaches after a previous design failed. Your advantage is not
12
12
  brilliance — it is discipline sustained over a long run.
13
13
 
14
+ <!-- actor-contract:start -->
15
+ ## Actor and evidence contract
16
+ - A script — the orchestrating agent — created you and hands you work one ask at a time. What you return is read by that script and acted on mechanically; there is no interactive user in this conversation. If you need a decision only a person can make, say so in your result; if you need information the orchestrator has, ask it directly in the report you return — it can answer and continue you — rather than guessing.
17
+ - You have file-edit, search, and shell tools. There is no tool that asks a person anything, no tool that shows your report to a user, and no tool that schedules work for later — the orchestrator reads your report as text, and you are the whole run.
18
+ - Ground every claim about the repo in something you read or ran in this run; report the command or file:line for each load-bearing claim.
19
+ <!-- actor-contract:end -->
20
+
14
21
  ## Operating contract
15
22
 
16
23
  1. **Restate the objective before acting.** Open every run by writing down,
@@ -0,0 +1,27 @@
1
+ {
2
+ "hooks": {
3
+ "PreToolUse": [
4
+ {
5
+ "matcher": "^(read|grep)$|^mcp__serena__",
6
+ "hooks": [
7
+ {
8
+ "type": "command",
9
+ "command": "node \"${CLAUDE_PLUGIN_ROOT}/hooks/serena-remind.mjs\"",
10
+ "timeout": 10
11
+ }
12
+ ]
13
+ }
14
+ ],
15
+ "SessionEnd": [
16
+ {
17
+ "hooks": [
18
+ {
19
+ "type": "command",
20
+ "command": "node \"${CLAUDE_PLUGIN_ROOT}/hooks/serena-session-cleanup.mjs\"",
21
+ "timeout": 10
22
+ }
23
+ ]
24
+ }
25
+ ]
26
+ }
27
+ }
@@ -0,0 +1,111 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Shared gating for the serena code-intelligence hooks shipped by this
4
+ * plugin (docs/plans/2026-09-22-serena-hooks-agents-plugin.md).
5
+ *
6
+ * dsh-cc-agents is enabled profile-wide, but the serena remind/cleanup hooks
7
+ * only make sense where serena is actually adopted. `runGatedSerenaHook`
8
+ * enforces that with two silent gates, so on non-serena projects each hook
9
+ * invocation costs one node spawn and nothing else:
10
+ *
11
+ * 1. Project gate — walk ancestors from the session project dir until a
12
+ * directory containing `.serena/project.yml` (serena's onboarding
13
+ * artifact) is found. The walk is inclusive of the git toplevel (`.git`
14
+ * file or directory) and stops at it, the filesystem root, or `$HOME`.
15
+ * Sessions launched in subdirectories still resolve the project root.
16
+ * 2. Binary gate — `serena-hooks` must resolve on `PATH` (plain fs scan;
17
+ * no `which` dependency).
18
+ *
19
+ * Both gates pass → spawn `serena-hooks <subcommand> --client claude-code`,
20
+ * piping the hook payload through stdin and extending the env with
21
+ * `SERENA_HOME=<projectRoot>/.serena` (the session sandbox's writable
22
+ * surface; serena's `~/.serena` default is outside it and its `save()`
23
+ * swallows the failure — the dead-counter incident fixed by PR #100). The
24
+ * child's stdout is relayed verbatim so the CC `hookSpecificOutput` response
25
+ * reaches the bridge unchanged.
26
+ *
27
+ * Exit-0 discipline (watchdog-script precedent): every failure path —
28
+ * unreadable stdin, no serena project, missing binary, spawn error, child
29
+ * timeout — exits 0 with no output. A hook must never break a tool call.
30
+ */
31
+ import { spawnSync } from 'node:child_process'
32
+ import { existsSync, readFileSync } from 'node:fs'
33
+ import { homedir } from 'node:os'
34
+ import { dirname, delimiter, join, resolve } from 'node:path'
35
+
36
+ /** Read the whole hook payload from stdin; empty/unparseable → undefined. */
37
+ function readPayload() {
38
+ let raw
39
+ try {
40
+ raw = readFileSync(0, 'utf8')
41
+ } catch {
42
+ return undefined
43
+ }
44
+ try {
45
+ const parsed = JSON.parse(raw)
46
+ return typeof parsed === 'object' && parsed !== null ? { raw, parsed } : undefined
47
+ } catch {
48
+ return undefined
49
+ }
50
+ }
51
+
52
+ function hasSerenaProject(dir) {
53
+ return existsSync(join(dir, '.serena', 'project.yml'))
54
+ }
55
+
56
+ /** Walk ancestors for the serena project root; stop at git toplevel (incl.), fs root, $HOME. */
57
+ export function findSerenaProjectRoot(startDir) {
58
+ const home = resolve(homedir())
59
+ let dir = resolve(startDir)
60
+ for (;;) {
61
+ if (hasSerenaProject(dir)) return dir
62
+ if (dir === home) return undefined
63
+ if (existsSync(join(dir, '.git'))) return undefined // toplevel reached, no serena there
64
+ const parent = dirname(dir)
65
+ if (parent === dir) return undefined
66
+ dir = parent
67
+ }
68
+ }
69
+
70
+ /** True when `bin` resolves on PATH (fs scan; win32 gets its suffix variants). */
71
+ export function resolvesOnPath(bin) {
72
+ const suffixes = process.platform === 'win32' ? ['', '.cmd', '.exe'] : ['']
73
+ for (const entry of (process.env.PATH ?? '').split(delimiter)) {
74
+ if (!entry) continue
75
+ for (const suffix of suffixes) {
76
+ if (existsSync(join(entry, bin + suffix))) return true
77
+ }
78
+ }
79
+ return false
80
+ }
81
+
82
+ /** Child lifetime cap stays below the hooks.json timeout (10s) with node-boot margin. */
83
+ const SPAWN_TIMEOUT_MS = 8000
84
+
85
+ /**
86
+ * Gate-and-run `serena-hooks <subcommand> --client claude-code`. Always
87
+ * resolves; never throws; process exits 0 regardless of outcome.
88
+ * @param {'remind' | 'cleanup'} subcommand
89
+ */
90
+ export function runGatedSerenaHook(subcommand) {
91
+ try {
92
+ const payload = readPayload()
93
+ const projectDir =
94
+ process.env.CLAUDE_PROJECT_DIR ??
95
+ (typeof payload?.parsed.cwd === 'string' ? payload.parsed.cwd : undefined) ??
96
+ process.cwd()
97
+ const projectRoot = findSerenaProjectRoot(projectDir)
98
+ if (projectRoot === undefined) return
99
+ if (!resolvesOnPath('serena-hooks')) return
100
+ const res = spawnSync('serena-hooks', [subcommand, '--client', 'claude-code'], {
101
+ input: payload?.raw ?? '',
102
+ encoding: 'utf8',
103
+ timeout: SPAWN_TIMEOUT_MS,
104
+ env: { ...process.env, SERENA_HOME: join(projectRoot, '.serena') },
105
+ })
106
+ if (res.error !== undefined && res.error !== null) return
107
+ if (typeof res.stdout === 'string' && res.stdout !== '') process.stdout.write(res.stdout)
108
+ } catch {
109
+ // Exit-0 discipline: swallow everything.
110
+ }
111
+ }
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * PreToolUse (`read|grep|mcp__serena__*`) hook: nudge the model toward
4
+ * serena's symbolic tools after a burst of raw reads/greps. Gated — see
5
+ * ./serena-gate.mjs; without a serena project this is a silent no-op.
6
+ */
7
+ import { runGatedSerenaHook } from './serena-gate.mjs'
8
+
9
+ runGatedSerenaHook('remind')
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * SessionEnd hook (detached on session dispose): garbage-collect this
4
+ * session's serena hook state (`<project>/.serena/hook_data/<session-id>`)
5
+ * so the per-session dirs do not accumulate. Gated — see ./serena-gate.mjs.
6
+ */
7
+ import { runGatedSerenaHook } from './serena-gate.mjs'
8
+
9
+ runGatedSerenaHook('cleanup')
package/package.json CHANGED
@@ -1,12 +1,13 @@
1
1
  {
2
2
  "name": "@dsh-cc/plugin-dsh-cc-agents",
3
- "version": "0.7.1",
4
- "description": "Official dsh-cc Claude-compatible plugin: the critic, executor, and marathon subagents plus an orchestration routing skill.",
3
+ "version": "0.8.0-rc.2",
4
+ "description": "Official dsh-cc Claude-compatible plugin: the critic, executor, and marathon subagents, an orchestration routing skill, and gated serena code-intelligence hooks.",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
7
7
  "files": [
8
8
  ".claude-plugin/plugin.json",
9
9
  "agents",
10
+ "hooks",
10
11
  "skills",
11
12
  "README.md"
12
13
  ],
@@ -0,0 +1,65 @@
1
+ ---
2
+ name: data-analysis
3
+ description: Meta-rules for orchestrating data-analysis tasks through the critic/executor pattern. Triggers — 数据分析 (data analysis), 利用率查询 (utilization query), 资源盘点 (resource inventory), 口径 (metrics caliber), 对账 (reconciliation), data analysis, reconciliation, utilization query, metrics caliber. Use when a task runs queries against a data platform, doubts or cross-checks metric calibers, or delivers a data report — route it per §D and inline §A-§C into the dispatch prompts.
4
+ ---
5
+
6
+ # Data-analysis orchestration meta-rules
7
+
8
+ Self-contained process discipline for data-analysis tasks. All domain
9
+ knowledge (dataset contracts, calibers, pitfalls, query scripts) lives in the
10
+ target workspace's own docs and skills; this skill adds none. The
11
+ orchestrator inlines the relevant sections into each dispatch prompt and
12
+ points subagents at the workspace files by workspace-relative path —
13
+ subagents start fresh, have `Read` but no skill tool, and cannot see this
14
+ skill.
15
+
16
+ ## §A Review meta-rubric (inline into critic dispatches)
17
+
18
+ - Does the spec identify the workspace's data-access contract and cite the
19
+ matching workspace-local skill or doc? If nothing matches, is it a
20
+ genuinely new query or a trigger-keyword gap?
21
+ - Is the caliber routing correct per the workspace's own contract document?
22
+ The critic never invents calibers.
23
+ - Does the spec state numeric expectations (magnitude, trend direction,
24
+ cross-check relationship)? A result without expectations is unreviewable:
25
+ reject and bounce back to the orchestrator rather than inventing them.
26
+
27
+ ## §B Verification discipline (inline into executor dispatches)
28
+
29
+ - Every numeric result ships with: full query parameters (dataset / region /
30
+ date window / filters, or the workspace's equivalents), row count, and the
31
+ spec'd cross-check result.
32
+ - Cross-checks prefer a second independent caliber or dataset; absent one,
33
+ fall back to time-series sanity (deltas, magnitude jumps).
34
+ - The executor reports numbers and deltas, never interpretations;
35
+ interpretation belongs to the orchestrator/critic.
36
+
37
+ ## §C Execution discipline (inline into executor dispatches)
38
+
39
+ - Iron order: preflight (auth/permission state per the workspace contract)
40
+ → find the matching workspace skill's existing scripts → reuse →
41
+ hand-write only on a genuine gap.
42
+ - For endpoints the preflight doesn't cover: a minimal probe (smallest
43
+ possible query) confirms reachability and permissions — never stall,
44
+ never guess.
45
+ - Before hand-writing anything, read the workspace's data-contract and
46
+ pitfalls docs; on zero rows or errors, match the trap checklist and retry
47
+ once before re-deriving.
48
+ - Throttling discipline: lightweight queries, sequential execution, backoff
49
+ on failure; never hammer a query API concurrently.
50
+ - Honest guardrail framing: where the data path is read-only, these rules
51
+ protect against wrong numbers, not damage; where writes exist, they must
52
+ be explicit in the spec.
53
+
54
+ ## §D Routing (the orchestrator's own rule)
55
+
56
+ - Escalation threshold: routine single-caliber query → the workspace's own
57
+ skill, a single agent. Caliber doubt / reconciliation / external
58
+ deliverable → multi-agent.
59
+ - Multi-agent loop: the orchestrator decomposes and lifts numeric
60
+ expectations from the workspace's skill/contract docs into the spec
61
+ (expectations are the orchestrator's to supply; the critic only verifies)
62
+ → critic reviews with §A inlined plus path pointers → executor executes
63
+ with §B/§C inlined plus path pointers → orchestrator synthesizes.
64
+ - Report delivery goes through the workspace's own skills, never through
65
+ multi-agent wrapping.
@@ -28,6 +28,11 @@ match a plugin definition.
28
28
  Independent delegations: batch them in one message (multiple Task calls in
29
29
  the same turn) instead of serializing them.
30
30
 
31
+ Data-analysis tasks (metrics-caliber/口径 doubt, cross-caliber
32
+ reconciliation/对账, external deliverable reports) route per the
33
+ `data-analysis` skill; routine single-caliber queries stay single-agent —
34
+ no multi-agent escalation.
35
+
31
36
  ## Background asymmetry (important)
32
37
 
33
38
  - **critic** is read-only, so it runs in the BACKGROUND by default —
@@ -73,3 +78,20 @@ critic carries `Bash` for read-only verification. Its read-only
73
78
  nature is a PERSONA CONTRACT, not an enforced restriction — the host does
74
79
  not block a mutating command from a backgrounded reasoner. Do not hand it
75
80
  tasks that tempt mutation, and review any backgrounded output before acting.
81
+
82
+ ## Writing subagent prompts (authoring rules)
83
+
84
+ Order: identity → tool surface → evidence/contract → evaluation criteria.
85
+ Evaluation never precedes capability: state what the agent has and lacks
86
+ before what you will grade it on. The tool surface is one positive sentence
87
+ ("You have file-edit, search, and shell tools.") followed by negative
88
+ exclusions that name behaviorally ABSENT surfaces only (e.g. "no tool that
89
+ asks a person anything") — never enumerate the frontmatter tool list, and
90
+ never copy surface names from other harnesses that do not exist in dsh-cc.
91
+
92
+ Gateable blocks: sections wrapped in `<!-- actor-contract:start -->` /
93
+ `<!-- actor-contract:end -->` (whole lines) are stripped at spawn unless the
94
+ resolved child model matches the `actor-contract.models` settings patterns
95
+ (default `['glm-*']`). Agents whose contract is GLM-specific (actor framing,
96
+ evidence rules) opt in by adding their own marked block near the identity
97
+ line; content outside markers reaches every model.