dsh-web
zhu1090093659/dsh-webDeepSeek Harness(DSH)Web 插件聚合生态包 · 一切皆插件,创意工坊分发(dsh-market.com)
English · 简体中文
A DSH plugin that keeps one versioned vocabulary of a project's business concepts, shows where the code spells them differently, and gives a person and an agent a place to decide which spelling is canonical.
DSH shows the plugin as Semantic Drift Vocabulary (语义漂移词表).
The idea is borrowed from kurapica/schema-node-csharp, which argues three things this plugin takes as given:
re-derived from the code on every read.
type system.
to remember.
No implementation is borrowed. There is no Meta/Property/Relation model, no semantic compilation, no code generation. One YAML file, one read-only scanner, one panel, five agent tools.
It records what things are called. Each concept gets one entry: a dotted id, the human terms for it, a kind, the canonical symbol (plus type and unit when they matter) and a note. The file is versioned with the project, so a rename is a diff someone can review.
It finds where the code disagrees. A read-only scan compares the tree with the vocabulary and reports:
never uses at all;
It works from an empty vocabulary too: the structural detectors compare code with code, so a fresh project has findings before its first concept exists.
It gives the decision a home. An accepted exception carries a reason and the smallest scope that covers the case. It can be edited, reworded, removed or undone later, and each one reports how many findings it actually mutes right now. The decision is a line in the vocabulary file, not a memory in someone's head.
It puts the vocabulary in front of the agent. Every session receives one prompt section with the concepts of the workspace it runs in, plus the rules: look the concept up before naming something, spell it exactly as the canonical symbol does, register a missing concept first, record a deliberate deviation with a reason. Five tools let the agent read, register, scan and adjudicate.
It costs tokens, and you can turn that off. The prompt section is the recurring cost; the panel's settings switch disables it per profile, and the scan itself costs nothing until someone asks for it. Numbers are in Token cost.
text. Two unrelated types that share a name can still be reported.
deviate, and the only defence is that the deviation must be recorded.
trusted precisely because it never writes your source.
declarations. Other files contribute comment/string evidence only.
canonical.unit is displayed and validated asa string; there is no unit-drift detector.
project decision; if you commit it, the team shares and reviews it.
Any of these installs the bundle into a profile:
# from npm
dsh plugin --profile desktop add dsh-semantic-drift
# from GitHub
dsh plugin --profile desktop add github:Yubickari/dsh-semantic-drift
# from a local checkout
dsh plugin --profile desktop add link:/path/to/dsh-semantic-driftThe Web GUI offers the same under Settings → Plugins → Install from source. After installing, refresh the page once so the browser half loads, then pick Semantic Drift Vocabulary in the sidebar.
lib/ is committed, so installing from a git source needs no build step. The plugin needs DSH >=0.2.1-rc.3.
There is no in-plugin updater: DSH replaces an installed bundle when it is installed again.
# npm, a specific version
dsh plugin --profile desktop add dsh-semantic-drift@0.2.0
# GitHub, pinned to a tag
dsh plugin --profile desktop add github:Yubickari/dsh-semantic-drift#v0.2.0Restart DSH afterwards, then read the version in the panel footer (vX.Y.Z) or at GET /semantic-drift/health; the settings dialog no longer repeats it. An update never touches your vocabulary file or its accepted exceptions.
.dsh/semantics.yaml with the defaultexclusions and no concepts.
type is defined twice"), which is the cold-start value.
semantic_upsert) and scan again.Vocabulary-dependent findings now have something to compare against.
directory with the same file name, the whole symbol, or a custom glob), read the count it will mute, and write a reason.
version: 1
meta:
project: demo
updated: 2026-10-25
exclude: ["**/node_modules/**", "**/bin/**", "**/obj/**"]
concepts:
- id: device.target_temperature # group.name, unique
terms: ["target temperature", "set point"] # what humans call it
kind: quantity # entity | quantity | enum | status | reference
canonical:
symbol: TargetTemperature # what the code must call it
type: double
unit: "°C"
note: The temperature the device is asked to reach.
accepted: # decided exceptions, each with a reason
- symbol: TargetTemp
path: src/Legacy/** # a glob; omit to accept the symbol everywhere
reason: public field kept for one releaseterms may be written in any language: the scanner matches them as plain text in comments, strings and resource files.
Validation runs before every write; a document that fails is never written, and the reported issue carries the YAML line or the document path:
id must be unique and look like group.name;canonical.symbol must be a plain identifier and unique across concepts;terms must be non-empty and cannot be shared between two concepts;accepted entry needs a reason;untouched.
Saving is canonical and idempotent. Hand edits in the raw editor keep their own formatting.
Detector · Confidence · Signal duplicate-type · high · same members and same values in two units: a real copy, and merging it is a safe suggestion · high · *derived copy*: same member names, different values, one shared base type — a parameterized derivative, never a merge candidate · high · *same names, different values*: no shared base, so the two sides disagree about what those names mean contract-drift · high · the same type in two units with different members, or with different values for the same members. Skipped when one type shadows its own base, or when both are private nested helpers symbol-variant · medium · a spelling variant of canonical.symbol (case/separator form, a known confusable, edit distance ≤ 2), or *same contract, other name*: same base, members and stable literal as the canonical type · medium · *vocabulary spelling is not in the code*: canonical.symbol appears nowhere as a code token while another case form is declared or heads a declaration term-unmapped · low · a declared term appears in comments or resources, but the canonical symbol never appears in code
Every finding also carries a stable rule id in detail.rule, which is what the panel localizes:
rule · detector · meaning identical-members · duplicate-type · same members and the same values derived-copy · duplicate-type · same members, different values, one shared base literal-variant · duplicate-type · same members, different values, no shared base diverged-members · contract-drift · members or their values differ normalized · symbol-variant · same spelling after removing case and separators confusable · symbol-variant · a known misspelling of a token in the symbol edit-distance · symbol-variant · within two edits of the canonical contract-alias · symbol-variant · same contract, another name canonical-case · symbol-variant · canonical spelling absent, another case present canonical-missing · term-unmapped · a term is used, the canonical symbol is not
Member values are compared when they are simple single-line literals: two enums whose members swapped values used to look identical when only names were compared. A copy declared as a struct on one side and a class on the other says so in the message.
Two filters keep the list short: a variant only fires when the file also mentions a term of the concept, or both spellings share the same leading token; a contract-drift pair must share at least one member.
Deliberately excluded: entry-point classes (Program/Startup with a Main), partial declarations, generated files (*.Designer.cs, *.g.cs, auto-generated headers), declarations with fewer than two members, subclasses that shadow a base of the same name, and private nested helpers.
Tool · Purpose semantic_list · list concepts; hasDrift runs a scan and filters to concepts with findings semantic_get · one concept by id or symbol, plus its accepted exceptions; includeDrift adds a scan semantic_upsert · create or update a concept (merge keeps omitted fields, replace rebuilds it) drift_scan · structured findings with detector, confidence and citation semantic_accept · add (default), update scope or reason, remove one, clear a concept; reason is required to add or update. previousPath locates the entry to change
With announceToAgent on, every session receives one prompt section: the concepts of the workspace it runs in and the rules that go with them. The section is capped at 200 lines and summarized past 120 concepts. Turn it off in the panel to stop the recurring token cost; the tools stay available.
A refusal is always a value ({ ok: false, code, message, issues }), never an exception. A vocabulary file that cannot be parsed is reported as valid: false with its first issues.
The loop this is built for:
semantic_get for the concept it is about totouch;
semantic_upsert before any code is written;drift_scan shows whether the change introduced a variant or adivergence;