dsh-doublecheck 0.9.29 → 0.9.31

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.
Files changed (62) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/LICENSE +0 -0
  3. package/PRIVACY.md +11 -0
  4. package/README.en.md +577 -0
  5. package/README.es.md +577 -0
  6. package/README.hi.md +577 -0
  7. package/README.md +369 -247
  8. package/README.pt.md +577 -0
  9. package/cordis.patch.yml +0 -0
  10. package/icon.svg +1 -0
  11. package/lib/ci.d.ts +0 -0
  12. package/lib/ci.js +0 -0
  13. package/lib/domain/evidence.d.ts +7 -6
  14. package/lib/domain/evidence.js +15 -21
  15. package/lib/domain/gate.d.ts +0 -0
  16. package/lib/domain/gate.js +0 -0
  17. package/lib/domain/projection.d.ts +0 -0
  18. package/lib/domain/projection.js +0 -0
  19. package/lib/domain/report.d.ts +6 -0
  20. package/lib/domain/report.js +1 -1
  21. package/lib/domain/stages.d.ts +0 -0
  22. package/lib/domain/stages.js +0 -0
  23. package/lib/domain/vagueness.d.ts +0 -0
  24. package/lib/domain/vagueness.js +0 -0
  25. package/lib/domain/vocabulary.d.ts +0 -0
  26. package/lib/domain/vocabulary.js +0 -0
  27. package/lib/events.d.ts +2 -0
  28. package/lib/events.js +0 -0
  29. package/lib/grill/index.d.ts +0 -0
  30. package/lib/grill/index.js +84 -26
  31. package/lib/grill/provider.d.ts +0 -0
  32. package/lib/grill/provider.js +0 -0
  33. package/lib/guard/activation.d.ts +0 -0
  34. package/lib/guard/activation.js +0 -0
  35. package/lib/guard/command.d.ts +0 -0
  36. package/lib/guard/command.js +1 -0
  37. package/lib/guard/gate.d.ts +0 -0
  38. package/lib/guard/gate.js +0 -0
  39. package/lib/guard/index.d.ts +0 -0
  40. package/lib/guard/index.js +30 -25
  41. package/lib/guard/prose.d.ts +0 -0
  42. package/lib/guard/prose.js +0 -0
  43. package/lib/guard/review.d.ts +0 -0
  44. package/lib/guard/review.js +0 -0
  45. package/lib/index.d.ts +0 -0
  46. package/lib/index.js +0 -0
  47. package/lib/invariant.d.ts +0 -0
  48. package/lib/invariant.js +0 -0
  49. package/lib/session-events.d.ts +0 -0
  50. package/lib/session-events.js +0 -0
  51. package/lib/types.d.ts +0 -0
  52. package/lib/types.js +0 -0
  53. package/package.json +38 -29
  54. package/skills/delivery-proof/SKILL.md +0 -0
  55. package/skills/delivery-review/SKILL.md +0 -0
  56. package/skills/grill-requirements/SKILL.md +0 -0
  57. package/skills/red-green-tdd/SKILL.md +0 -0
  58. package/strict.patch.yml +0 -0
  59. package/README-es.md +0 -449
  60. package/README-hi.md +0 -449
  61. package/README-pt.md +0 -449
  62. package/README-zh.md +0 -449
package/CHANGELOG.md CHANGED
@@ -1,5 +1,25 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.9.31] - 2026-11-13
4
+
5
+ ### Fixed
6
+
7
+ - **`verify: true` now finds the engine that lives in the agent preset.** In the web profile the workflow engine is mounted inside the calling preset's isolated `delegation` group, so `ctx.get('workflowEngine')` from the profile-level grill plugin returns `undefined` and every report silently fell back to `Not run.`. The lookup now goes through the host's cross-realm accessor `agentPresets.serviceFor(agent, 'workflowEngine')` first and keeps the plain `ctx.get` as the fallback for host-plane profiles. Fixes #22.
8
+ - **A verification attempt that did not run now says why.** Every failure path (no spec, no owning agent, unreachable engine, rejected `start`, early `stopReason`, malformed value, rejected result) carries a note that renders as `Not run — <reason>` instead of a bare `Not run.`; the same note is on the report value (`verificationNote`) and the `doublecheck/report` event. Run disposal failures no longer fail the report call. Fixes #22.
9
+
10
+ ## [0.9.30] - 2026-11-05
11
+
12
+ ### Changed
13
+
14
+ - Align with the DSH **0.2.2** host line. Every `@deepseek-ai/dsh-*` devDependency that publishes a 0.2.2 release moves from `0.2.1-rc.2` to `0.2.2-rc.1`; `@deepseek-ai/dsh-invariants` stays at `0.2.0-rc.2` because that package has no 0.2.2 release. The cordis family moves to the vendors of 0.2.2 (`^4.1.0` / `^1.1.0`), `@deepseek-ai/schemastery` moves to `~3.19.0`, and `@deepseek-ai/dsh-package-manifest@0.2.2-rc.1` joins the devDependencies (0.2.2's published `dsh-llm` types import it without declaring it). `engines.dsh` gains the `>=0.2.2-0 <0.3.0` clause and `engines.node` gains the `>=24.9.0` clause. Peer ranges only widen: no host line is dropped, and the cordis/schemastery peer ranges stay at their old loose values.
15
+ - Add `@deepseek-ai/dsh-tool-executor-native@0.2.2-rc.1` as a devDependency. 0.2.2 moved raw batch execution behind a pluggable executor, so the test harnesses mount it after `ToolRuntime`.
16
+
17
+ ### Fixed
18
+
19
+ - `ctx.tools.execute()` in the grill and guard test harnesses uses the 0.2.2 batch contract (`calls: [{ type: 'tool-call', … }]` plus `signal`/`agent`, settling through `batch.results[0].result`). The batch-level `additionalContexts` is asserted where the removed single-call field used to carry it.
20
+ - The `doublecheck` session projection awaits the now-asynchronous `ctx.sessionProjections.register()` inside its effect, holds the returned handle, and releases it with `handle.dispose()` on unload. A new regression test mounts the REAL 0.2.2 registry and proves the key goes live and disappears on dispose.
21
+ - `ptcSettle()` matches both `tool/ptc-dispatch` and its predecessor `tool/code-dispatch` structurally. The 0.2.2 tools contract retires the typed PTC event while persistence still recognizes both labels, so a restored pre-upgrade log keeps folding.
22
+
3
23
  ## [0.9.29] - 2026-10-19
4
24
 
5
25
  ### Fixed
package/LICENSE CHANGED
File without changes
package/PRIVACY.md ADDED
@@ -0,0 +1,11 @@
1
+ # Privacy
2
+
3
+ `dsh-doublecheck` is a local DeepSeek Harness plugin.
4
+
5
+ - It reads only the workspace files, configuration and tool inputs needed for its documented features.
6
+ - It does not add telemetry, analytics, advertising or a hosted account, and it sends no data to PerryLink.
7
+ - Any network access or external service used by the plugin is documented in its README and is controlled by the user's own configuration.
8
+ - It writes no data outside the DSH profile, the workspace, and the host's own session/log storage. The host controls that storage and its retention.
9
+ - Removing the package removes its code; it does not delete host logs, workspace files or documents you already created.
10
+
11
+ This statement covers the npm package, not the DSH host or any other plugin in the profile.
package/README.en.md ADDED
@@ -0,0 +1,577 @@
1
+ <div align="center">
2
+
3
+ <picture>
4
+ <source media="(prefers-color-scheme: dark)" srcset="docs/assets/dsh-doublecheck-hero-en-dark.webp">
5
+ <img src="docs/assets/dsh-doublecheck-hero-en-light.webp" width="100%" alt="dsh-doublecheck: the name and the headline Prove it first on the left; on the right the gate report a /gate run settles — requirements pass 6/6, tests are red because coverage is 61% against an 80% minimum, consistency carries one minor warning that does not flip the verdict, and the settled verdict is rework with one red item">
6
+ </picture>
7
+
8
+ # dsh-doublecheck
9
+
10
+ **Turn "it's done" into an evidence-backed verdict: grill the requirements first, prove the test red then green, and let a four-phase gate settle deliverable or rework before the handoff.**
11
+
12
+ The delivery quality gate for DeepSeek Harness: two plugin rows watch the same replayable session log and turn the grill → design → red → green → review → verify discipline loop into commands, tools, and one verdict that lands in a report.
13
+
14
+ [Install](#three-step-setup) · [Configuration](#configuration) · [FAQ](#faq) · [简体中文](README.md) · [English](README.en.md) · [Español](README.es.md) · [Português](README.pt.md) · [हिन्दी](README.hi.md)
15
+
16
+ [![License](https://img.shields.io/badge/license-Apache--2.0-3366CC?style=flat-square&labelColor=2B3245)](LICENSE)
17
+ [![DSH](https://img.shields.io/badge/DSH-%E2%89%A50.1.6%20%3C0.3.0-4B67B4?style=flat-square&labelColor=2B3245)](#compatibility)
18
+ [![npm](https://img.shields.io/npm/v/dsh-doublecheck?style=flat-square&labelColor=2B3245&color=CB3837)](https://www.npmjs.com/package/dsh-doublecheck)
19
+ [![CI](https://img.shields.io/github/actions/workflow/status/PerryLink/dsh-doublecheck/ci.yml?branch=main&label=CI&style=flat-square&labelColor=2B3245)](https://github.com/PerryLink/dsh-doublecheck/actions/workflows/ci.yml)
20
+ [![Node](https://img.shields.io/badge/node-%5E22.19%20%7C%7C%20%3E%3D24.9-339933?style=flat-square&labelColor=2B3245)](#compatibility)
21
+
22
+ [![Stars](https://img.shields.io/github/stars/PerryLink/dsh-doublecheck?style=flat-square&labelColor=2B3245)](https://github.com/PerryLink/dsh-doublecheck/stargazers)
23
+ [![npm downloads](https://img.shields.io/npm/dm/dsh-doublecheck?style=flat-square&labelColor=2B3245&color=CB3837)](https://www.npmjs.com/package/dsh-doublecheck)
24
+ [![dshfind](https://dshfind.com/api/badge/PerryLink/dsh-doublecheck?metric=downloads)](https://dshfind.com/plugins/PerryLink/dsh-doublecheck?ref=badge)
25
+ [![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/PerryLink/dsh-doublecheck/badge)](https://securityscorecards.dev/viewer/?uri=github.com/PerryLink/dsh-doublecheck)
26
+ [![DSH Market](https://img.shields.io/badge/DSH_Market-listed-4B67B4?style=flat-square&labelColor=2B3245)](https://dsh.market/)
27
+ [![Gitee](https://img.shields.io/badge/Gitee-mirror-C71D23?style=flat-square&labelColor=2B3245&logo=gitee)](https://gitee.com/perrylink/dsh-doublecheck)
28
+
29
+ ```sh
30
+ dsh plugin --profile <name> add dsh-doublecheck
31
+ ```
32
+
33
+ </div>
34
+
35
+ <sub>Community plugin, not affiliated with DeepSeek. Canonical repository: <https://github.com/PerryLink/dsh-doublecheck> (Gitee is a mirror).</sub>
36
+
37
+ ## What it is
38
+
39
+ `dsh-doublecheck` does not install a prompt; it installs two plugin rows. `doublecheck-grill` grills the requirements and commits them as a spec; `doublecheck-guard` holds the line at every edit, test, and handoff boundary. Both read the same durable session log, so after a resume, a fork, or a restart they see exactly the same evidence.
40
+
41
+ A `/gate run` folds what already happened in the session into a four-phase checklist — were the requirements confirmed one by one, is the latest test run red or green, does every edit serve a spec dimension, what does the review conclude — and settles one **deliverable / rework required** verdict, written as a report you can paste into a PR description.
42
+
43
+ It does not write your code and it does not judge how the code looks. It does one thing: it makes the sentence "it's done" carry evidence.
44
+
45
+ <picture>
46
+ <source media="(prefers-color-scheme: dark)" srcset="docs/assets/dsh-doublecheck-flow-v5-dark.svg">
47
+ <img src="docs/assets/dsh-doublecheck-flow-v5-light.svg" width="100%" alt="dsh-doublecheck structure: the durable session log on the left — tool/call, tool/result, user/message, autoReview/verdict, dsh-eval report plus doublecheck/state and doublecheck/gate — feeds four phase rows: requirements and tests fold deterministically with no model call, consistency and review each fork one read-only reviewer; only a failing check crosses into the verdict rail, warnings and skips never flip it, and the footer carries gate-report.md, gate-report.json, the CI exit code and the bounded one-line projection">
48
+ </picture>
49
+
50
+ ## Three-step setup
51
+
52
+ 1. **Install** (pick one channel):
53
+
54
+ ```sh
55
+ # git channel (latest main; the prepare script builds with production dependencies only)
56
+ dsh plugin --profile web add github:PerryLink/dsh-doublecheck
57
+ # npm channel (published releases)
58
+ dsh plugin --profile web add dsh-doublecheck
59
+ # tarball channel: pnpm pack in this repo, then
60
+ dsh plugin --profile web add ./dsh-doublecheck-<version>.tgz
61
+ ```
62
+
63
+ Both rows (`doublecheck-grill` and `doublecheck-guard`) activate with the profile.
64
+
65
+ 2. **Minimal config**: none is required — the bundle patch already inserts both rows; an id-targeted override has to restate the whole row's config (see "Configuration"). The equivalent profile-patch shape:
66
+
67
+ ```yaml
68
+ - insert:
69
+ - id: doublecheck-grill
70
+ name: 'dsh-doublecheck/grill'
71
+ - id: doublecheck-guard
72
+ name: 'dsh-doublecheck/guard'
73
+ ```
74
+
75
+ 3. **Verify it mounts**:
76
+
77
+ ```sh
78
+ dsh --profile web --dump-config | grep -E -A3 'id: doublecheck-(grill|guard)'
79
+ ```
80
+
81
+ ```text
82
+ > /doublecheck status
83
+ > /gate status
84
+ ```
85
+
86
+ **Uninstall**: `dsh plugin --profile web remove dsh-doublecheck` (or remove the two rows from the profile patch).
87
+
88
+ > Want a zero-configuration strict mode — every gate on at `block` intensity, with coverage evidence required — apply the shipped overlay on top of the bundle patch: `dsh --profile web --patch ./node_modules/dsh-doublecheck/strict.patch.yml`.
89
+
90
+ ## Core capabilities
91
+
92
+ Every checkpoint in `dsh-doublecheck` takes its evidence from the session log, not from a claim that "I tested it":
93
+
94
+ - **Requirements furnace (`doublecheck-grill`)** — the bundled `grill-requirements` skill, the model-facing `doublecheck_skills`, `doublecheck_spec`, and `doublecheck_report` tools, and the per-dimension verification workflow. No consensus, no implementation.
95
+ - **Discipline guard (`doublecheck-guard`)** — the grill gate, the red/green evidence gates, the adversary review, the `/doublecheck` and `/gate` commands, the live `gate` settings card, and the four-phase delivery gate, at `remind` / `warn` / `block` intensity.
96
+ - **Evidence from the log, not from self-reports** — every injected reminder, review, and gate notice rides the standard channels into the session log; durable facts ride `doublecheck/state`, `doublecheck/gate`, or tool results. Replay is the state, so a resumed or forked session re-derives the same `/gate run` result.
97
+ - **One failed check, one red light** — a missing spec, a latest run that is not green, coverage below the threshold, an edit unmapped to any spec dimension, or a blocker/major finding each becomes a red light with a rework suggestion; warnings and skips never flip the verdict.
98
+ - **Audit-safe** — gate and delivery reports record counts, ids, and verdicts only, with no file contents or session text; model-produced finding texts pass a secret redactor before storage or display.
99
+
100
+ The loop is one line: grill → design → red → green → review → verify. Each step leaves replayable evidence, while the six requirement dimensions, the consensus gate, and the structured spec land in both the session and the workspace.
101
+
102
+ The six stages of the discipline loop:
103
+
104
+ | Stage | Meaning |
105
+ |---|---|
106
+ | **grill** | Interrogate the six requirement dimensions; refuse to implement until consensus. |
107
+ | **design** | The settled spec is committed via `doublecheck_spec`. |
108
+ | **red** | A failing test run proves the gap before implementation edits. |
109
+ | **green** | A passing test run after the edits closes the loop. |
110
+ | **review** | A forked adversary critic audits the delivery against the spec. |
111
+ | **verify** | `doublecheck_report` plus a per-dimension verification workflow prove the delivery. |
112
+
113
+ ## Tools & surfaces
114
+
115
+ | Surface | Kind | Notes |
116
+ |---|---|---|
117
+ | `doublecheck_skills` | tool | Lists and loads the package's four bundled skills through the skill registry seam. |
118
+ | `doublecheck_spec` | tool | Commits the grilled six-dimension spec to the session log and a workspace markdown copy. |
119
+ | `doublecheck_report` | tool | Folds the discipline evidence into a delivery report (optional per-dimension verification workflow). |
120
+ | `/doublecheck status\|report\|on\|off` | command | Switch, modules, intensity, stage facts, folded report, and the durable on/off override. |
121
+ | `/gate status\|run\|config` | command | Live checklist progress, the settled deliverable/rework report, and the effective config. |
122
+ | `grill-requirements`, `red-green-tdd`, `delivery-review`, `delivery-proof` | skill | Bundled discipline skills covering all six loop stages. |
123
+ | `gate` | live config field | The pluggable checklist is the guard row's one `.volatile()` field: it is edited from the row's settings card (namespace = the row's profile entry id) and read once at load. |
124
+ | `strict.patch.yml` | overlay | Every gate on at `block` intensity plus the coverage requirement, in one patch layer. |
125
+ | `dsh-doublecheck/invariant` | companion row | Reports package-owned write-path contradictions through the host `invariants` registry. |
126
+ | `doublecheck` | session projection | One bounded status line a client renders: stage, latest gate verdict, red-light count, edits, spec/review flags. See [Reading the status line](#reading-the-status-line). |
127
+
128
+ ### Reading the status line
129
+
130
+ The `doublecheck` session projection is a plain **string**, and it is deliberately one line — the whole point is that a client can show it without cutting anything off. A chat bridge's `/status`, a status bar, or any custom consumer renders it as it is:
131
+
132
+ ```text
133
+ gate:rework r2 | stage:green | test:green edits:12 spec:yes review:yes | goal:ship parser fix
134
+ ```
135
+
136
+ | Segment | Reads as |
137
+ |---|---|
138
+ | `gate:<verdict> r<n>` | The latest delivery-gate verdict — `none` before any run, `deliverable`, or `rework` — and its red-light count `r<n>`. |
139
+ | `stage:<stage>` | The discipline stage reached on durable evidence: `grill`, `design`, `red`, `green`, `review`, `verify`. |
140
+ | `test:<color>` | The latest test-run color: `none`, `red`, `green`. |
141
+ | `edits:<n>` | Implementation edits folded from the session log (test-file writes are not counted). |
142
+ | `spec:yes` / `spec:no` | Whether a committed `doublecheck_spec` exists. |
143
+ | `review:yes` / `review:no` | Whether an adversary review record exists. |
144
+ | `goal:<excerpt>` | The committed spec goal, clipped. Present only when `spec:yes`. |
145
+
146
+ The line is bounded **by construction**, so no renderer truncates it:
147
+
148
+ - Hard budget: **120 characters**. A renderer that keeps values up to 120 characters — the WeChat bridge's generic projection renderer is one — shows the entire line. The old object-shaped payload was 131 characters when *empty*, which is why the verdict and the red count used to be cut off.
149
+ - The first three segments are **lossless**. Counts above `9999` red lights or `99999` edits print as `9999+` / `99999+` instead of growing without bound; a non-finite or negative count prints as `0`.
150
+ - `goal:` is the one lossy segment. It is flattened to a single line (newlines and control characters become spaces, `|` becomes `/`) and clipped to the budget that is left, at most 40 characters, ending in `…` when it was clipped. The complete goal is in `/doublecheck status` and the delivery report.
151
+ - This is a glance, not the record: `/gate status` and `/doublecheck status` render the full state.
152
+
153
+ The projection's `stateVersion` is **3**. Bumping it discards a persisted projection-cache row written by an older version and refolds the key from the session log, so an upgraded session recomputes the line instead of showing a stale one. The persisted fold state itself is unchanged, and a pre-upgrade session never fails to load.
154
+
155
+ ## Gate phases
156
+
157
+ The delivery gate aggregates the session's durable evidence into a configurable four-phase checklist and settles one **deliverable / rework required** decision. Every phase folds the session log alone (replay IS the state), so a run re-derives identically after resume or fork.
158
+
159
+ | Phase | Checks | Evidence source | Model cost |
160
+ |---|---|---|---|
161
+ | Requirements interrogation | Key-question checklist confirmed item by item (six spec-dimension questions by default) | Committed `doublecheck_spec` + `ask_user_question` calls | none |
162
+ | Test evidence | Latest run color, failing runs after green, optional coverage threshold, optional dsh-eval report | Shell test runs in the session log (`[exit code: N]`, coverage percentages); the dsh-eval report file when `gate.tests.evalReports.enabled` | none |
163
+ | Implementation consistency | Diff ↔ requirement mapping: every edit must serve a spec dimension | Local forked reviewer (structured findings, read-only tools) | one subagent |
164
+ | Review conclusion | The delivery verdict; `engine: auto` consumes dsh-auto-review's durable verdict records when present, else the local reviewer | `autoReview/verdict` / `autoReview/rejection` events, or the local forked reviewer | one subagent (local) |
165
+
166
+ Red lights are failed checks (a missing spec, a failing latest run, coverage below minimum, an unmapped edit, blocker/major findings) — each carries a rework suggestion. Warnings and skips never flip the decision. The gate integrates [dsh-auto-review](https://github.com/PerryLink/dsh-auto-review) as a weak dependency: `review.engine: auto` folds its verdict records when present and degrades to the local reviewer otherwise; `gate.tests.evalReports.enabled` folds its eval engine's dsh-eval report (prompt-regression / stress / fairness suites) into the test evidence and skips honestly when no report exists. The gate never synthesizes approval requests.
167
+
168
+ ## Examples
169
+
170
+ These are the plugin's real entry points; install once, then call one.
171
+
172
+ ### Detailed example
173
+
174
+ **Command**
175
+
176
+ ~~~sh
177
+ /gate run
178
+ ~~~
179
+
180
+ **Output**
181
+
182
+ ~~~text
183
+ # Delivery gate report
184
+
185
+ > **Verdict: rework required** — 2 red item(s)
186
+ > The gate is red. Re-open the work in plan mode to re-check the open items before delivering.
187
+ ~~~
188
+
189
+ *Observed from `README.md §Example report (lines 243-251)`*
190
+
191
+ ### Failure branch
192
+
193
+ **Input**
194
+
195
+ ~~~text
196
+ /doublecheck maybe
197
+ ~~~
198
+
199
+ **Output**
200
+
201
+ ~~~text
202
+ Unknown /doublecheck argument "maybe". Usage: /doublecheck status|report|on|off
203
+ ~~~
204
+
205
+ *Observed from `plugins/dsh-doublecheck/src/guard/prose.ts:191-192; plugins/dsh-doublecheck/src/guard/command.ts:156; plugins/dsh-doublecheck/tests/command.spec.ts:201-208`*
206
+
207
+ ### Brief examples
208
+
209
+ - `doublecheck_skills`
210
+ - `doublecheck_spec`
211
+
212
+ ### Example report
213
+
214
+ `/gate run` returns this markdown — paste it into a PR description:
215
+
216
+ ````markdown
217
+ # Delivery gate report
218
+
219
+ > **Verdict: rework required** — 2 red item(s)
220
+ > The gate is red. Re-open the work in plan mode to re-check the open items before delivering.
221
+
222
+ ## 1. Requirements interrogation — PASS
223
+ - [✔] **What outcome must the delivery produce?** — spec dimension "goal" committed
224
+ - [✔] **What is in scope, and what is out of scope?** — spec dimension "scope" committed
225
+ - [✔] **Which observable checks prove the work is done?** — spec dimension "acceptanceCriteria" committed
226
+ - [✔] **What can go wrong, and what is the correct behavior in each case?** — spec dimension "failureModes" committed
227
+ - [✔] **What is traded when goals conflict; what is optional?** — spec dimension "priorities" committed
228
+ - [✔] **What does the user explicitly not want?** — spec dimension "nonGoals" committed
229
+
230
+ ## 2. Test evidence — FAIL
231
+ - [✔] **passing test run** — latest test run passed
232
+ - [✔] **failing cases after green** — 0 failing run(s) after green (allowed: 0)
233
+ - [✖] **coverage evidence** — 61% coverage below the 80% minimum — rework: raise coverage above the configured minimum
234
+
235
+ ## 3. Implementation consistency — WARN
236
+ - [⚠] **[minor] src/telemetry.ts touched without a requirement** — [minor] the edit adds a metric no spec dimension covers
237
+
238
+ ## 4. Review conclusion — PASS
239
+ - [✔] **dsh-auto-review conclusion** — 3 call(s) approved by dsh-auto-review (latest risk: low)
240
+
241
+ ## Red items
242
+ 1. **tests/coverage** — 61% coverage below the 80% minimum — *rework: raise coverage above the configured minimum*
243
+ 2. **consistency/finding-1** — [minor] the edit adds a metric no spec dimension covers — *rework: src/telemetry.ts touched without a requirement*
244
+
245
+ ## Audit
246
+ - review engine: dsh-auto-review
247
+ - generated at: 2026-08-14T12:00:00.000Z
248
+ - counts, ids, and verdicts only: no file contents or session text are embedded, and recognized secrets are redacted.
249
+ ````
250
+
251
+ ### CI output
252
+
253
+ `/gate run` also writes a `gate-report.json` (the same settled state as lossless JSON, next to `gate-report.md`). The `doublecheck-gate` CLI turns that file into machine-readable output for GitHub Actions:
254
+
255
+ ```sh
256
+ # JSON (PR comment / status payload)
257
+ doublecheck-gate --format json --input gate-report.json
258
+ # SARIF 2.1.0 (code-scanning upload / status check)
259
+ doublecheck-gate --format sarif < gate-report.json
260
+ ```
261
+
262
+ The CLI only serializes the already-settled `GateState` — it never re-runs the four-phase gate or the evidence folds. Its exit code maps the verdict: `0` = deliverable, `1` = rework, `2` = usage/parse error.
263
+
264
+ ## Configuration
265
+
266
+ All tunables are Schemastery `Config` fields (changeable from cordis.yml). An id-targeted override replaces the whole row — restate every key you need. `cordis.patch.yml` documents each key inline; Schema defaults are the single source of tuning defaults.
267
+
268
+ Most-used keys:
269
+
270
+ | Key | Default | Meaning |
271
+ |---|---|---|
272
+ | `specFile` | `'doublecheck-spec.md'` | Workspace file for the committed spec markdown (grill row). |
273
+ | `reportFile` | `'doublecheck-report.md'` | Workspace file for the delivery report (grill row). |
274
+ | `intensity` | `'remind'` | Enforcement strength of the grill, red/green, and review gates (`remind` / `warn` / `block`). |
275
+ | `enableByDefault` | `true` | Master switch for sessions without a `/doublecheck on\|off` record. |
276
+ | `language` | `'en'` | Injected reminder/deny/review/gate prose language (`en` / `zh`). |
277
+ | `modules.adversary` | `false` | On enables the forked critic review at green. |
278
+ | `gate.enabled` | `true` | Master switch for the gate panel and the turn-boundary red notice. |
279
+ | `gate.review.engine` | `'auto'` | `auto` = dsh-auto-review verdict records when present, else the local reviewer; `local` = always local. |
280
+
281
+ <details>
282
+ <summary>Full configuration table (39 keys)</summary>
283
+
284
+ | Key | Default | Meaning |
285
+ |---|---|---|
286
+ | `specFile` | `'doublecheck-spec.md'` | Workspace file for the committed spec markdown (grill row). |
287
+ | `reportFile` | `'doublecheck-report.md'` | Workspace file for the delivery report (grill row). |
288
+ | `reportVerify` | `true` | Run the verification workflow by default (grill row). |
289
+ | `verifyProvider` | `'fork'` | Subagent provider for the per-dimension checkers (grill row). |
290
+ | `verifyMode` | `'all'` | `all` = one parallel checker per dimension; `single` = one combined checker (grill row). |
291
+ | `intensity` | `'remind'` | Enforcement strength of the grill, red/green, and review gates (`remind` / `warn` / `block`). |
292
+ | `enableByDefault` | `true` | Master switch for sessions without a `/doublecheck on\|off` record. |
293
+ | `language` | `'en'` | Injected reminder/deny/review/gate prose language (`en` / `zh`). |
294
+ | `guardTools` | `['edit', 'write']` | Mutation tool names both gates watch. |
295
+ | `vagueTaskMaxChars` | `200` | Longer tasks are never treated as vague. |
296
+ | `remindOnce` | `true` | Inject each reminder at most once per session (durable across restarts). |
297
+ | `testToolNames` | `['bash', 'pwsh']` | Shell tool names that can run tests. |
298
+ | `testCommandPatterns` | *(pnpm / npm / yarn / bun test, pytest, go / cargo / make test, node --test, deno test, uv run pytest)* | Regexes a command must match to count as a test run. |
299
+ | `testFilePatterns` | *(test dirs, `*.test.*` / `*.spec.*`)* | Regexes identifying test files — always editable, exempt from the red gate. |
300
+ | `modules.grill` | `true` | Off disables the grill gate. |
301
+ | `modules.tdd` | `true` | On enables the red/green evidence gates. |
302
+ | `modules.adversary` | `false` | On enables the forked critic review at green. |
303
+ | `adversaryModel` | `null` | Critic model route; `null` = main model self-reviews. |
304
+ | `adversaryProvider` | `'fork'` | Subagent provider the critic runs on. |
305
+ | `adversaryMaxFindings` | `5` | Findings cap (1–20) injected into the session. |
306
+ | `adversaryTools` | `['read', 'glob', 'grep']` | Critic tool allowlist; keep it read-only. |
307
+ | `adversaryTimeoutMs` | `120000` | Hard time budget for one critic run. |
308
+ | `gate.enabled` | `true` | Master switch for the gate panel and the turn-boundary red notice. |
309
+ | `gate.planSuggestion` | `true` | Append the plan-mode re-check suggestion to red reports. |
310
+ | `gate.reportFile` | `'gate-report.md'` | Workspace file for the gate report. |
311
+ | `gate.requirements.checklist` | *(six spec-dimension questions)* | Pluggable key-question checklist: `{ id, question, specDimension, required }`. |
312
+ | `gate.requirements.minConfirmed` | `6` | Minimum required questions that must pass (1..required count). |
313
+ | `gate.requirements.interrogateTool` | `'ask_user_question'` | Tool name whose calls count as interrogation evidence. |
314
+ | `gate.tests.requirePassingRun` | `true` | A non-passing (or missing) latest test run is a red light. |
315
+ | `gate.tests.allowFailingRuns` | `0` | Failing runs after the latest green allowed before red. |
316
+ | `gate.tests.requireCoverage` | `false` | On requires coverage evidence in the test output. |
317
+ | `gate.tests.minCoveragePct` | `80` | Minimum coverage percentage (0–100). |
318
+ | `gate.tests.evalReports.enabled` | `false` | On folds the dsh-eval report (dsh-auto-review's eval engine) into the test evidence. |
319
+ | `gate.tests.evalReports.dir` | `'.eval-reports'` | Workspace-relative directory holding the engine's report. |
320
+ | `gate.tests.evalReports.file` | `'report.json'` | Report file name inside the directory. |
321
+ | `gate.tests.evalReports.required` | `false` | A missing report is a red light exactly when true (a skip otherwise). |
322
+ | `gate.consistency.*` | `provider: 'fork'`, `model: null`, `tools: ['read','glob','grep']`, `timeoutMs: 120000`, `maxFindings: 5` | The local consistency reviewer's knobs (`model: null` = main model). |
323
+ | `gate.review.engine` | `'auto'` | `auto` = dsh-auto-review verdict records when present, else the local reviewer; `local` = always local. |
324
+ | `gate.review.provider` | `'fork'` | The local review reviewer's provider (its `model`/`tools`/`timeoutMs`/`maxFindings` match `gate.consistency.*`). |
325
+
326
+ </details>
327
+
328
+ Every `gate.*` key above is one **live field**: the guard row marks the whole `gate` block `.volatile()`, so it is the row's editable settings card (the form namespace is the row's profile entry id). The remaining keys are ordinary composition config from the profile patch. The block is read once at load, so an edit takes effect on the next load — `gate.enabled` decides whether the turn-boundary red notice is installed at all. On a host line whose schemastery predates `.volatile()` the row still mounts: the card is absent and the block comes from the profile patch exactly as before.
329
+
330
+ Misconfiguration fails loud at load: invalid regexes, empty or duplicated name lists, out-of-range thresholds, and duplicate checklist ids throw instead of silently doing nothing. `strict.patch.yml` is the all-gates-block overlay that restates the guard row at `intensity: block` with every module on and the coverage requirement enabled.
331
+
332
+ Example override in your profile patch:
333
+
334
+ ```yaml
335
+ - insert:
336
+ - id: doublecheck-guard
337
+ name: 'dsh-doublecheck/guard'
338
+ config:
339
+ language: zh
340
+ intensity: block
341
+ modules:
342
+ tdd: true
343
+ adversary: true
344
+ gate:
345
+ tests:
346
+ requireCoverage: true
347
+ ```
348
+
349
+ ## FAQ
350
+
351
+ <details>
352
+ <summary>Where does the data live? Can a report leak my file contents?</summary>
353
+
354
+ Durable facts are two session events, `doublecheck/state` (the durable switch) and `doublecheck/gate` (the settled gate state), plus four workspace files — `doublecheck-spec.md`, `doublecheck-report.md`, `gate-report.md`, `gate-report.json` (paths configurable). Gate and delivery reports record counts, ids, and verdicts only: no file contents and no session text, and model-produced finding texts pass a secret redactor before storage or display. Nothing outside the session workspace is touched.
355
+
356
+ </details>
357
+
358
+ <details>
359
+ <summary>What happens on hosts without durable appends? Silent breakage?</summary>
360
+
361
+ Nothing is silent. The durable records behind `/doublecheck on|off` and `/gate run` ride the host's `ignorable` append surface; on a host without it the writes are skipped and the switch falls back to process-local state (see Known limitations). The guard row's settings card needs the settings service: where the host's schemastery predates `.volatile()` there is no card, but the row still mounts and the `gate` block still comes from the profile patch. When a reviewer or adversary seam cannot run, the conclusion is written honestly as "unavailable"/skip instead of a fabricated verdict.
362
+
363
+ </details>
364
+
365
+ <details>
366
+ <summary>Does it fight other plugins over command names, events, or slots?</summary>
367
+
368
+ No. Every tool is namespaced, it provides no service key, registers no client slot and no `webServer` prefix, and every shared-event listener delegates through `next()` and never short-circuits the chain. The point-by-point argument is in "Interoperability with other DSH plugins".
369
+
370
+ </details>
371
+
372
+ <details>
373
+ <summary>How many model calls does one `/gate run` cost?</summary>
374
+
375
+ The requirements and test-evidence phases are pure folds with no model cost; the consistency and review-conclusion phases start one forked subagent each (with `gate.review.engine: auto` and dsh-auto-review verdict records present, the review-conclusion phase can be consumed at zero cost). The optional adversary review adds one more. Nothing else calls a model or the network.
376
+
377
+ </details>
378
+
379
+ ## Security boundaries
380
+
381
+ - **Model-visible ⟺ logged.** Every injected reminder, review, and gate notice rides the standard channels and lands in the session log; the durable spec/state/gate facts ride tool results or `SessionEventMap` members.
382
+ - **Fail closed / fail loud.** Guard and gate config are validated in `apply` (assertions throw); a reviewer or adversary seam that cannot run settles as an honest "unavailable"/skip notice instead of a fake verdict.
383
+ - **Audit-safe reports.** Gate and delivery reports record counts, ids, and verdicts only — no file contents or session text — and model-produced finding texts pass a secret redactor before storage or display.
384
+ - **No network of its own.** The plugin makes no direct network requests; the critic and reviewer subagents ride the harness subagent seam.
385
+ - **Weak dependency on dsh-auto-review.** It is never imported or hard-required; the gate folds its durable verdict records and degrades to the local reviewer, and never synthesizes approval requests.
386
+
387
+ ## Permissions & data
388
+
389
+ - **Reads**: the session log (`tool/call` / `tool/result` / `tool/ptc-dispatch`, injected `user/message` sources, and the foreign `autoReview/*` verdict records) in-process only; the optional plan-mode service state. PTC sub-dispatches carry the predecessor `tool/code-dispatch` label on hosts before the V3 rename; both labels fold identically. Injected notices carry the producer-owned `dsh-doublecheck` message-source kind; logs recorded before that kind existed arrive as `plugin:dsh-doublecheck` (the harness's V3→V4 migration on a released catch-all wrapper) or as the released `plugin` wrapper, and all three fold identically.
390
+ - **Writes**: `doublecheck-spec.md`, `doublecheck-report.md`, `gate-report.md`, and `gate-report.json` in the session workspace (paths configurable) through the `ctx.fs` seam; the durable `doublecheck/state` and `doublecheck/gate` session events.
391
+ - **Model calls**: the gate's consistency and local-review phases (one subagent each per `/gate run`), the optional adversary review, and the `doublecheck_report` verification workflow start subagent runs; nothing else calls a model or the network.
392
+ - **Never touched**: credentials, environment variables, or any file outside the session workspace. The workshop manifest declares `filesystem:read` and `filesystem:write` only. Gate reports carry counts, ids, and verdicts only; recognized secrets in reviewer texts are redacted before storage or display.
393
+
394
+ ## Known limitations
395
+
396
+ - **Durable writes.** `/doublecheck on\|off` → `doublecheck/state` and `/gate run` → `doublecheck/gate` ride the host's `ignorable` append surface (post-rc.6 through `0.1.1-rc.2`). On hosts without that surface (rc.6/rc.8, and `0.1.2-alpha.1`, which removed the envelope — `0.1.2-rc.1` restores the field for stored-log read compatibility only and still cannot stamp it), the writes are skipped and the switch stays process-local.
397
+ 0.1.2-rc.1 (adapted 2026-09-02): the session envelope keeps its ignorable field for stored-log read compatibility only - Session.append still cannot stamp it, so audit-gate behavior is unchanged.
398
+ 0.1.5-alpha.1 (adapted 2026-09-09): session format V3 renames the durable sub-dispatch event `tool/code-dispatch` to `tool/ptc-dispatch` (payload unchanged; both labels fold identically). Session.append still exposes no `ignorable` channel, so durable writes stay skipped and the switch stays process-local - behavior unchanged. (The `doublecheck-gate` settings namespace this entry introduced was removed in 0.1.7-alpha.1, when the harness deleted the namespace registry.)
399
+ 0.1.5-rc.1 (adapted 2026-09-10): dependency pins move to the published 0.1.5-rc.1 line; no seam change affects this plugin's behavior.
400
+ 0.1.5-rc.2 (adapted 2026-09-11): dependency pins move to the published 0.1.5-rc.2 line; no seam change affects this plugin's behavior.
401
+ 0.1.7-alpha.1 (adapted 2026-10-04): the harness deleted the shared catch-all `plugin` message-source kind (notices now carry the producer-owned `dsh-doublecheck` kind, and the `remindOnce` fold still reads the two pre-upgrade shapes a durable log can hold), and it replaced the settings-namespace registry with `SettingsForms` (the `doublecheck-gate` namespace is gone; the gate checklist is now the guard row's one `.volatile()` field, still read once at load). Dev/test pins for `@deepseek-ai/cordis` and `@deepseek-ai/schemastery` move to `^4.0.3` / `^3.18.3`, where `Volatile` and `.volatile()` first exist; the peer ranges stay `^4.0.2` / `^3.18.2` and the live-field surface is detected at load, so the older host lines mount the row with no settings card. No behavior change beyond the settings storage location.
402
+ - **Optional seams.** The guard row's settings card appears when the settings service is mounted; the card is this row's own Config (namespace = its profile entry id), and the `gate` block is read once at load, so its values apply to the `/gate` panel and the gate-red notice on the next load. The live-field surface is detected at load, so on a host line whose schemastery predates `.volatile()` the row mounts anyway — without a card, with the `gate` block taken from the profile patch. The `/gate status` plan-mode line reads the optional `ctx.planMode` (shows `unknown` without it); the adversary review needs `ctx.subagents`; verification needs `workflowEngine`.
403
+ - **Local degrade.** `gate.review.engine: auto` degrades to the local reviewer when dsh-auto-review is absent or has no verdict records this session — the report names the reason instead of inventing a verdict.
404
+ - **dsh-eval evidence is file-based.** The dsh-auto-review eval engine (`dsh-eval`) writes its prompt-regression / stress / fairness results to a workspace report file, not the session log. `gate.tests.evalReports.enabled` folds that file (off by default; skips when absent) and the folded counts ride the durable `doublecheck/gate` record so a settled run still replays.
405
+
406
+ ## Interoperability with other DSH plugins
407
+
408
+ Verified against **DSH `0.2.0-rc.2`** (the runtime this README ships for) and the high-star plugin set surveyed on 2026-10-05.
409
+
410
+ This plugin **does not interfere** with other plugins, including the widely installed high-star ones:
411
+
412
+ - **No tool-name collision.** Every tool is namespaced; no bare name owned by a shipped tool or another plugin is registered.
413
+ - **No service-key collision.** It provides no service key at all, so it cannot collide on one.
414
+ - **No slot collision.** It registers no client slot key, so it cannot contend for a `shadows-shipped-ui` seat.
415
+ - **No HTTP route collision.** It registers no `webServer` prefix.
416
+ - **No patch-layer collision.** The bundle patch only `insert`s its own row; it never overrides a built-in row's `config`.
417
+ - **No global mutation.** It does not patch prototypes, rewrite `process.env`, or replace the global fetch dispatcher.
418
+
419
+ **Shared event listeners are non-interfering by construction.** It observes the ordering-sensitive events `agent/turn-stopping`, `tools/post-execute`, `tools/pre-execute` with `ctx.on()` — Cordis's broadcast registration, where every listener runs and none can starve another. **Every listener here delegates through `next()`**, so the chain is never short-circuited, and a mutation is applied to the value `next()` produced rather than returned in its place:
420
+
421
+ - `tools/post-execute` — also used by `cc-safety-net` (1576★).
422
+ - `tools/pre-execute` — also used by `cc-safety-net` (1576★).
423
+
424
+ Static evidence: `dsh-plugin-doctor` K10–K13 report `pass` for every check on this repository.
425
+
426
+ ## Compatibility
427
+
428
+ | Surface | Status |
429
+ |---|---|
430
+ | Harness | DeepSeek Harness `dsh-v0.2.2-rc.1` (adapted 2026-11-05): `engines.dsh` gains `>=0.2.2-0 <0.3.0` (every earlier line stays admitted); the gate and projection paths are covered by the rc.1 test suite. |
431
+ | Node | `^22.19.0 \|\| >=24.9.0` |
432
+ | Platforms | All (pure host; no native code, no direct network requests of its own) |
433
+ | Model | Any (the guard itself never calls a model; the critic and reviewer phases run as harness subagents) |
434
+
435
+ ## Ecosystem & quality
436
+
437
+ - [Gitee mirror](https://gitee.com/perrylink/dsh-doublecheck) (sync mirror; GitHub is canonical)
438
+ - [dshfind plugin page](https://dshfind.com/plugins/PerryLink/dsh-doublecheck) (installs and ranking)
439
+ - [OpenSSF Scorecard report](https://securityscorecards.dev/viewer/?uri=github.com/PerryLink/dsh-doublecheck) (driven by [.github/workflows/scorecard.yml](.github/workflows/scorecard.yml))
440
+ - [dsh-plugin-doctor verification report](https://github.com/PerryLink/dsh-plugin-doctor#verified-徽章) (K10–K13 all `pass`)
441
+ - [DSH Market](https://dsh.market/) (listed)
442
+ - **1024 store channel**: `npm i -g dsh1024` once, then `dsh1024 plugin --profile web add dsh-doublecheck` (counts toward the [deepseek1024.com](https://deepseek1024.com) install ranking)
443
+ - [Ecosystem knowledge base](https://perrylink.github.io/dsh-plugin-guide/) — measured data, not marketing: plugin development guide · plugin-selection data · maintenance criteria
444
+
445
+ ## Development
446
+
447
+ ```sh
448
+ pnpm install # node ^22.19 || >=24
449
+ pnpm run build # tsc --noEmitOnError (lib/ is committed)
450
+ pnpm run prepare # tsc --noEmitOnError (git-install channel)
451
+ pnpm run prepublishOnly # build + full test suite
452
+ pnpm run typecheck # tsc --noEmit + tests tsconfig
453
+ pnpm run lint # eslint src tests
454
+ pnpm test # vitest run
455
+ pnpm run test:coverage # vitest run --coverage
456
+ pnpm run pack:check # build + pack the tarball
457
+ pnpm run check:readmes # five-language README consistency gate
458
+ ```
459
+
460
+ `lib/` is committed on purpose: the git-install channel resolves the package without a build step, so rebuild with `pnpm run build` and commit the regenerated tree after source changes. The README images are generated programmatically by [`scripts/gen-readme-assets.py`](scripts/gen-readme-assets.py): Pillow draws the hero banner (zh/en × light/dark WebP) and hand-written SVG draws the structure diagram (flow-v5, light/dark), so the script is safe to re-run and overwrites idempotently. The older single-skin flow diagram and demo images stay in `docs/assets/` for external links; the READMEs reference only the new hero and flow-v5.
461
+
462
+ Topics: `dsh`, `dsh-plugin`, `deepseek-harness`, `engineering-discipline`, `requirements`, `guard`, `skill`, `quality-gate`, `delivery-gate`
463
+
464
+ ## Family & thanks
465
+
466
+ This project is part of the DeepSeek Harness plugin family from [PerryLink](https://github.com/PerryLink) (all Apache-2.0). If it is useful, **a star helps the next person find it** — nothing is gated behind it.
467
+
468
+ - [@PerryLink](https://github.com/PerryLink) — creator and maintainer: the grill → design → red → green → review → verify discipline loop, the four-phase delivery gate, the five-language docs, and the CI/release pipeline.
469
+
470
+ <details>
471
+ <summary>Expand all plugins</summary>
472
+
473
+ | Plugin | Status |
474
+ |---|---|
475
+ | **[dsh-aqua-input-check](https://github.com/PerryLink/dsh-aqua-input-check)** | |
476
+ | **[dsh-archive-check](https://github.com/PerryLink/dsh-archive-check)** | |
477
+ | **[dsh-auto-review](https://github.com/PerryLink/dsh-auto-review)** | |
478
+ | **[dsh-autotier](https://github.com/PerryLink/dsh-autotier)** | 🧊 FROZEN — see the repo README |
479
+ | **[dsh-bid-ca-precheck](https://github.com/PerryLink/dsh-bid-ca-precheck)** | |
480
+ | **[dsh-bid-qual-check](https://github.com/PerryLink/dsh-bid-qual-check)** | |
481
+ | **[dsh-cert-mcp](https://github.com/PerryLink/dsh-cert-mcp)** | 🧊 FROZEN — see the repo README |
482
+ | **[dsh-checkpoint-rewind](https://github.com/PerryLink/dsh-checkpoint-rewind)** | |
483
+ | **[dsh-click](https://github.com/PerryLink/dsh-click)** | |
484
+ | **[dsh-composer-history](https://github.com/PerryLink/dsh-composer-history)** | |
485
+ | **[dsh-contract-stance](https://github.com/PerryLink/dsh-contract-stance)** | |
486
+ | **[dsh-customs-doc-check](https://github.com/PerryLink/dsh-customs-doc-check)** | |
487
+ | **[dsh-data-quality](https://github.com/PerryLink/dsh-data-quality)** | 🧊 FROZEN — see the repo README |
488
+ | **[dsh-demurrage-ledger](https://github.com/PerryLink/dsh-demurrage-ledger)** | |
489
+ | **[dsh-doublecheck](https://github.com/PerryLink/dsh-doublecheck)** | |
490
+ | **[dsh-drill-script-check](https://github.com/PerryLink/dsh-drill-script-check)** | |
491
+ | **[dsh-eia-guide-check](https://github.com/PerryLink/dsh-eia-guide-check)** | |
492
+ | **[dsh-emergency-plan](https://github.com/PerryLink/dsh-emergency-plan)** | |
493
+ | **[dsh-essay-rubric-check](https://github.com/PerryLink/dsh-essay-rubric-check)** | |
494
+ | **[dsh-evidence-check](https://github.com/PerryLink/dsh-evidence-check)** | |
495
+ | **[dsh-export-ctl-check](https://github.com/PerryLink/dsh-export-ctl-check)** | |
496
+ | **[dsh-fast](https://github.com/PerryLink/dsh-fast)** | |
497
+ | **[dsh-fmea-table-check](https://github.com/PerryLink/dsh-fmea-table-check)** | |
498
+ | **[dsh-forecast-penalty](https://github.com/PerryLink/dsh-forecast-penalty)** | |
499
+ | **[dsh-fund-research](https://github.com/PerryLink/dsh-fund-research)** | |
500
+ | **[dsh-github](https://github.com/PerryLink/dsh-github)** | |
501
+ | **[dsh-gongwen-flow-check](https://github.com/PerryLink/dsh-gongwen-flow-check)** | |
502
+ | **[dsh-gongwen-word-check](https://github.com/PerryLink/dsh-gongwen-word-check)** | |
503
+ | **[dsh-guard-plan-qc](https://github.com/PerryLink/dsh-guard-plan-qc)** | |
504
+ | **[dsh-hazchem-check](https://github.com/PerryLink/dsh-hazchem-check)** | |
505
+ | **[dsh-hazplan-check](https://github.com/PerryLink/dsh-hazplan-check)** | |
506
+ | **[dsh-hidden-risk-map](https://github.com/PerryLink/dsh-hidden-risk-map)** | |
507
+ | **[dsh-hs-classify](https://github.com/PerryLink/dsh-hs-classify)** | |
508
+ | **[dsh-icd-rule-check](https://github.com/PerryLink/dsh-icd-rule-check)** | |
509
+ | **[dsh-industry-research](https://github.com/PerryLink/dsh-industry-research)** | |
510
+ | **[dsh-lawcite-adapter](https://github.com/PerryLink/dsh-lawcite-adapter)** | |
511
+ | **[dsh-laya](https://github.com/PerryLink/dsh-laya)** | |
512
+ | **[dsh-lc-doc-check](https://github.com/PerryLink/dsh-lc-doc-check)** | |
513
+ | **[dsh-learning-gap-check](https://github.com/PerryLink/dsh-learning-gap-check)** | |
514
+ | **[dsh-library](https://github.com/PerryLink/dsh-library)** | |
515
+ | **[dsh-local-ai](https://github.com/PerryLink/dsh-local-ai)** | |
516
+ | **[dsh-lsp-actions](https://github.com/PerryLink/dsh-lsp-actions)** | |
517
+ | **[dsh-mask](https://github.com/PerryLink/dsh-mask)** | |
518
+ | **[dsh-mcp-panel](https://github.com/PerryLink/dsh-mcp-panel)** | |
519
+ | **[dsh-medrec-qc](https://github.com/PerryLink/dsh-medrec-qc)** | |
520
+ | **[dsh-memento](https://github.com/PerryLink/dsh-memento)** | 🧊 FROZEN — see the repo README |
521
+ | **[dsh-nsfc-form-check](https://github.com/PerryLink/dsh-nsfc-form-check)** | |
522
+ | **[dsh-nurse-record-check](https://github.com/PerryLink/dsh-nurse-record-check)** | |
523
+ | **[dsh-observe](https://github.com/PerryLink/dsh-observe)** | |
524
+ | **[dsh-origin-rvc-check](https://github.com/PerryLink/dsh-origin-rvc-check)** | |
525
+ | **[dsh-ota-review-check](https://github.com/PerryLink/dsh-ota-review-check)** | |
526
+ | **[dsh-output-styles](https://github.com/PerryLink/dsh-output-styles)** | |
527
+ | **[dsh-paper-doc-adapter](https://github.com/PerryLink/dsh-paper-doc-adapter)** | |
528
+ | **[dsh-permission-rules](https://github.com/PerryLink/dsh-permission-rules)** | |
529
+ | **[dsh-permit-report-check](https://github.com/PerryLink/dsh-permit-report-check)** | |
530
+ | **[dsh-pipeline-check](https://github.com/PerryLink/dsh-pipeline-check)** | |
531
+ | **[dsh-pleading-draft](https://github.com/PerryLink/dsh-pleading-draft)** | |
532
+ | **[dsh-plugin-doctor](https://github.com/PerryLink/dsh-plugin-doctor)** | 🚫 RETIRED (repo archived) |
533
+ | **[dsh-plugin-guide](https://github.com/PerryLink/dsh-plugin-guide)** | |
534
+ | **[dsh-plugin-kit](https://github.com/PerryLink/dsh-plugin-kit)** | 🚫 RETIRED (repo archived) |
535
+ | **[dsh-plugin-upgrade](https://github.com/PerryLink/dsh-plugin-upgrade)** | 🚫 RETIRED (repo archived) |
536
+ | **[dsh-policy-brief-draft](https://github.com/PerryLink/dsh-policy-brief-draft)** | |
537
+ | **[dsh-power-loss-split](https://github.com/PerryLink/dsh-power-loss-split)** | |
538
+ | **[dsh-power-ticket-check](https://github.com/PerryLink/dsh-power-ticket-check)** | |
539
+ | **[dsh-ppap-check](https://github.com/PerryLink/dsh-ppap-check)** | |
540
+ | **[dsh-protest-deadline](https://github.com/PerryLink/dsh-protest-deadline)** | |
541
+ | **[dsh-railway-window](https://github.com/PerryLink/dsh-railway-window)** | |
542
+ | **[dsh-repair-order-qc](https://github.com/PerryLink/dsh-repair-order-qc)** | |
543
+ | **[dsh-research-report](https://github.com/PerryLink/dsh-research-report)** | |
544
+ | **[dsh-review-reply-check](https://github.com/PerryLink/dsh-review-reply-check)** | |
545
+ | **[dsh-rulefile-check](https://github.com/PerryLink/dsh-rulefile-check)** | |
546
+ | **[dsh-safety-brief-check](https://github.com/PerryLink/dsh-safety-brief-check)** | |
547
+ | **[dsh-score](https://github.com/PerryLink/dsh-score)** | 🧊 FROZEN — see the repo README |
548
+ | **[dsh-session-sync](https://github.com/PerryLink/dsh-session-sync)** | |
549
+ | **[dsh-site-log-check](https://github.com/PerryLink/dsh-site-log-check)** | |
550
+ | **[dsh-skill-pack-security](https://github.com/PerryLink/dsh-skill-pack-security)** | |
551
+ | **[dsh-soe-decision-check](https://github.com/PerryLink/dsh-soe-decision-check)** | |
552
+ | **[dsh-soilwater-check](https://github.com/PerryLink/dsh-soilwater-check)** | |
553
+ | **[dsh-sop-sync-check](https://github.com/PerryLink/dsh-sop-sync-check)** | |
554
+ | **[dsh-spc-gbt-adapter](https://github.com/PerryLink/dsh-spc-gbt-adapter)** | |
555
+ | **[dsh-talk](https://github.com/PerryLink/dsh-talk)** | |
556
+ | **[dsh-tender-extract](https://github.com/PerryLink/dsh-tender-extract)** | |
557
+ | **[dsh-tender-matrix](https://github.com/PerryLink/dsh-tender-matrix)** | |
558
+ | **[dsh-test-drive](https://github.com/PerryLink/dsh-test-drive)** | |
559
+ | **[dsh-ticktick](https://github.com/PerryLink/dsh-ticktick)** | 🚫 RETIRED (repo archived) |
560
+ | **[dsh-translate](https://github.com/PerryLink/dsh-translate)** | |
561
+ | **[dsh-warranty-calc](https://github.com/PerryLink/dsh-warranty-calc)** | |
562
+ | **[dsh-budget](https://github.com/PerryLink/dsh-budget)** | 🧊 FROZEN — see the repo README |
563
+ | **[dsh-claude-move](https://github.com/PerryLink/dsh-claude-move)** | 🧊 FROZEN — see the repo README |
564
+ | **[dsh-defend](https://github.com/PerryLink/dsh-defend)** | 🧊 FROZEN — see the repo README |
565
+ | **[dsh-draw](https://github.com/PerryLink/dsh-draw)** | 🧊 FROZEN — see the repo README |
566
+ | **[dsh-reach](https://github.com/PerryLink/dsh-reach)** | 🧊 FROZEN — see the repo README |
567
+ | **[dsh-background-agents](https://github.com/PerryLink/dsh-background-agents)** | 🚫 RETIRED (repo archived) |
568
+ | **[dsh-session-pin](https://github.com/PerryLink/dsh-session-pin)** | 🚫 RETIRED (repo archived) |
569
+ | **[dsh-team-rooms](https://github.com/PerryLink/dsh-team-rooms)** | 🚫 RETIRED (repo archived) |
570
+
571
+ </details>
572
+
573
+ ## License
574
+
575
+ [Apache License 2.0](LICENSE) © 2026 dsh-doublecheck contributors
576
+
577
+ <p align="center"><sub>Apache-2.0 · Community plugin, not affiliated with DeepSeek.</sub></p>