DeepSeek Harness plugin

dsh-grayprint

GrayPrint — live reasoning-style meter for the DeepSeek Harness web chat. Places the current session's reasoning between two empirically calibrated poles: the first-person narrative style of the dsv4

Jump to install

Source facts

Repository
HongzhongL/dsh-grayprint
Latest update
Aug 21, 2026
Category
Memory
GitHub stars
3
Format
plugin
Catalog evidence
Upstream dsh.bundle evidence
Evidence path
package.json#dsh.bundle
Checked against
0.1.0-rc.8
Upstream check date
2026-08-20

This evidence comes from the upstream catalog. This site has not installed, run, or security-reviewed the plugin.

Install

Start with a prompt that asks an agent to review the GitHub repository and source. Switch to the command if you want to install it yourself.

Copy this prompt into DSH, Codex, or another agent and ask it to review the GitHub repository and source first.

Do not install or run any commands yet. Read this plugin's GitHub repository, README, and relevant source code. Then answer the questions below clearly and directly so I can decide whether it fits my needs:

1. What is this plugin, and what problem does it solve?
2. Who is it for, and what are its typical use cases?
3. How is it used after installation? Include one minimal example.
4. What known limitations or privacy, security, compatibility, or maintenance risks does it have?
5. Give a clear recommendation: recommend, conditionally recommend, or do not recommend, with reasons.

Distinguish statements documented by the repository, inferences from source code, and unknowns. If evidence is insufficient, say so explicitly. Do not guess or simply repeat the README.

GitHub: https://github.com/HongzhongL/dsh-grayprint
Plugin: dsh-grayprint
Author: HongzhongL

Check the source files

Read the README and other files from this plugin directory before installing.

File explorer4 files
README.en.mdSource · read only
README language

GrayPrint · reasoning-style fingerprints for dsh

中文 | English

![Awesome dsh-plugin](https://github.com/awesome-dsh-plugin/awesome-dsh-plugin)

A DeepSeek Harness (dsh) web plugin that starts at the bottom-right of the chat page with two independent live fingerprints: (1) whether the current reasoning text resembles the grayscale or current-release corpus, and (2) whether paragraph openers inside reasoning blocks lean toward Let me exploration or We need planning. Both describe writing form; neither proves model identity or capability.

PoleStyleEvidence
🟢 Grayscale fingerprintFirst-person narrative: I'm planning out… I'll set up… I've got…41 dsv4-grayscale opencode sessions shared on opncd.ai — 1,749 raw reasoning blocks / 7,870 internal paragraphs
🔵 Current-release fingerprintCollective-person shorthand: We need answer likely… Let's inspect…, not full sentences41 current-release DSH sessions on the standard preset3,021 raw reasoning blocks / 53,994 internal paragraphs

Why these two poles

This started as a check on whether NoLetMe's criterion holds on this corpus. It does not — the polarity is inverted: total let me matches are not stable enough to enter the grayscale score. Only Let me / We need at the start of an internal paragraph feed a separate organization-style tendency. GrayPrint v0.4 uses one consistent unit everywhere: split each reasoning block into its actual Markdown paragraphs, then inspect only the start of each paragraph.

A correction that mattered

v0.1's control group was wrong. Its "current" pole came from the anchored-standard preset — a preset explicitly designed to anchor the model back onto the minimal telegraphic trajectory. Using it as the representative of the current release baked the conclusion into the premise. Re-testing across 169 real sessions stratified by preset showed that the same current model swings from 10% to 86% purely by changing preset, and 8 current-release sessions were misclassified as grayscale.

With standard as the control, and with each reasoning block split into internal paragraphs, the real separation is:

Axis (per internal paragraph)GrayscaleCurrent standardSingle-axis accuracyWeight
First-person openers (I'm / I'll / I've / I)22.15%3.76%93.9%49%
Paragraphs opening with I'm / I'll14.94%1.28%96.3%51%
Paragraphs opening with we / let's (count only)0.0%1.13%54.9% (chance)
Paragraphs opening with We / Let's / Need (count only)0.0%1.35%54.9% (chance)
Mean of session-median paragraph lengths (display only)342 chars198 chars95.1%

Both scored axes are paragraph-opening rates: each internal paragraph can contribute at most once, and repeated words later in the same paragraph are not accumulated. The we / let's weak axis is near chance, so its progress, gray-direction rating, and weight have been removed; only its paragraph-opener count remains. The broader We / Let's / Need opener count and paragraph length are display-only. Let me is counted only as an opener for the independent organization fingerprint.

Paragraph unit

reasoning block is a transport container, not a statistical paragraph. The plugin normalizes CRLF to LF, splits each non-empty block on one or more blank lines, trims the parts, and discards empties. The raw block count remains visible as a separate detail. The two grayscale axes, the Let me ↔ We need fingerprint, the style-signal guard, and sample gates all use paragraph openers. Runtime no longer collects or displays whole-text word frequencies; Raw statistics contains opener counts and non-frequency metadata only.

The classifier

Two weighted paragraph-opening axes (the broad first-person axis is linear; the low-frequency I'm / I'll opener axis uses log10(x+0.01) to spread the low end, with each axis clamped to [0,1] between the two poles). The detail label “Relative axis position” is the normalized location between the current-release and grayscale references—not an opener rate or model probability; the actual rate appears separately under “This session.” Weights are normalized at runtime. Score ≥55% → Grayscale fingerprint, ≤25% → Current-release fingerprint, in between → Mixed.

Asymmetric evidence gate: a grayscale verdict additionally requires ≥48 internal paragraphs. Grayscale is the surprising claim, and paragraph-opening ratios are unstable on small samples. Below 48 paragraphs the panel reports "leaning grayscale, sample small". Ordinary samples below 5 internal paragraphs receive no verdict.

Paragraph-opening style tendency (independent, v0.4)

The second progress bar is independent of the grayscale score and counts openers of internal paragraphs inside reasoning blocks:

  • Let me… / Now, let me… → exploratory pole
  • We need… / Now, we need… → planning pole

Progress is We need openers / (Let me openers + We need openers). Fewer than three matching paragraphs produces “not enough fingerprint evidence” instead of an artificial 50%. The panel labels the chips and Let me opener rate explicitly; raw block counts remain separate. This helps distinguish organization styles inside the current release, but does not claim that wording alone causes quality.

Validation

Holdout accuracy 94.2% (200 random 70/30 splits, threshold re-chosen inside each training fold; each split first segments internal paragraphs and then extracts opener-only features). That is the honest figure — the 96.3% claimed by v0.1 was measured on the same data used to design the thresholds.

Shipped code against the full corpora:

CorpusnGrayscaleMixedCurrentGuard-refused
Grayscale opencode (41 sessions / 1,749 raw blocks / 7,870 paragraphs)4138111
Current standard (41 sessions / 3,021 raw blocks / 53,994 paragraphs)4114297
Current, other presets (out of calibration, 49 sessions)4902416

These figures come from the same backup corpus snapshot. Raw reasoning blocks and internal paragraphs are separate units and should not be read as the same sample size.

Score quantiles: grayscale median 96% (p25 79%); current standard median 5% (p75 14%); current other presets median 0%. Pybm06QA is the lowest-scoring grayscale sample (13%, Current), while 6AWmBTvh has a high score but only 47 internal paragraphs, so the asymmetric gate reports “leaning grayscale, sample small”. One current standard session lands in the grayscale band, reinforcing that this is a style similarity—not model identification.

Six guards (refusing to fake a reading)

1. Chinese reasoning — refuses a verdict above 15% CJK. 2. Other non-English text — refuses when Latin letters are below 40% of all letters, preventing Japanese, Korean, Russian, etc. from falling into the current-release band. 3. Weak English style evidence — even Latin-script text is refused when I'm / I'll / we / let's signals are too sparse, preventing French or Spanish from receiving a false current-release verdict. 4. Too few paragraphs — no verdict below 5 internal reasoning paragraphs. 5. Asymmetric gate — a grayscale verdict needs ≥48 internal paragraphs. 6. No reasoning at all — reports the anomaly instead of inventing a trajectory from visible reply text.

Honest limits

  • The two poles come from different rendering channels: grayscale from opencode share pages (narrative presentation), current from DSH's native reasoning blocks. Part of the gap may be the channel rather than the model version — this has not been ruled out. Ruling it out needs sessions of the current model running through opencode; the archive is grayscale-era and has none.
  • The grayscale side has positives only (community-curated before publishing — survivorship bias). Neither side carries task scores or a rubric.
  • Preset matters more than version: the same model spans 10%–86% across presets, so a grayscale reading cannot infer a model version.
  • Therefore this panel measures the narrative person of reasoning, not capability, backend, routing, or checkpoint identity.

Install

Prerequisite: dsh CLI ≥ 0.1.0-rc.7, with a target profile.

From GitHub (recommended) — no build permission needed. lib/ is hand-written and committed; there is no prepare script, so pnpm has nothing to approve:

dsh plugin --profile web add github:HongzhongL/dsh-grayprint

Pin a commit if you prefer: github:HongzhongL/dsh-grayprint#<sha>.

From a local tarball (built with npm pack, or downloaded from an existing release):

dsh plugin --profile web add ./dsh-grayprint-<version>.tgz

From a local checkout:

git clone https://github.com/HongzhongL/dsh-grayprint.git
dsh plugin --profile web add ./dsh-grayprint

Restart the dsh web host, then refresh the page. Removal: dsh plugin --profile web remove dsh-grayprint.

Usage

The panel starts bottom-right, and both the expanded card and collapsed chip are draggable. They share one user-position anchor; expansion is temporarily clamped inward so the full card remains visible. A short click on the sticky header collapses it, while a long press or drag does not misfire, and both directions are animated. The default view keeps only the grayscale-sample fingerprint and the independent Let me ↔ We need opener-style tendency; the two scored axes and raw opener counts live in a disclosure section. The UI follows dsh's Chinese/English locale, persists open and position state in localStorage, and always states that style similarity does not identify the actual model version.

Data scope and privacy

  • Counts reasoning blocks only (kind === 'reasoning') in the browser's current session snapshot. Visible reply text is used solely to diagnose the "no reasoning" anomaly and does not feed any style statistic.
  • Each reasoning block is split into internal Markdown paragraphs; classifier axes, organization fingerprints, style guards, and sample gates inspect paragraph starts only. Runtime retains no whole-text word frequencies; raw block counts, paragraph lengths, and opener counts are displayed separately.
  • Per-block paragraph counts are cached in a WeakMap, with the current text checked on every hit. If the host mutates an existing block object in place, GrayPrint recounts it instead of retaining stale paragraph totals and opener counts.
  • Nothing leaves your browser.

Architecture

lib/index.js   # Node (host) half — no-op, satisfies the Loader
lib/client.js  # browser bundle (hand-written closure factory, no build step)
               #   counting engine / classifier / guards / live session source / store / panel
evidence/profile.json  # the calibration record
test.mjs              # dependency-free engine, language-guard, dual-fingerprint, and disposal tests

The browser bundle is a window.__ModuleLoader__.load({id, factory}) closure-factory artifact; externals resolve through the injected require (this plugin only needs react). It mounts through the official shell.overlay slot and uses the official locale service. Session subscriptions, the stats store, and injected styles are tied to the plugin lifecycle and disposed on hot reload or uninstall. No existing UI is modified or patched.

Acknowledgements

The initial criterion came from NoLetMe (Yuer6327) and xiaobright/modeltest's trajectory research. The grayscale corpus comes from opncd.ai share links collected by YunhaoFu/dsv4ga-news-gather. GrayPrint reaches a different conclusion; the reasons are documented above.

License

[MIT](LICENSE)