Introduction¶
People who develop DSH plugins have often seen this kind of requirement: giving an agent a set of long-term memory. As diaries get longer, the model’s ability to judge the current status of “me and this person” isn’t necessarily better than just reading a few diary entries. The reason is straightforward—once the session changes and context is cut off, yesterday’s words are as if they were never said. When asked difficult questions, the model will first say “I don’t know” and then use “let’s talk about it later” to pass the time.
Existing memory plugins mostly solve “how to remember”: automatic extraction, layering, decay, and injection. They answer “what to remember”. dsh-diary-relation-check takes a step back and does only one thing: when memory is updated, remind the model to read through the layers, independently review a relationship, must give a judgment and reason, and then write the result into the state file without touching the diary body. The judgment is the model’s job, and the plugin’s responsibility is to ensure this task isn’t skipped.
Below is an introduction to the plugin’s positioning, working mechanism, installation method, and configuration.
What is it¶
The plugin is maintained by CatisAkaLi. Repository address: https://github.com/CatisAkaLi/dsh-diary-relation-check. It belongs to the memory category of plugins in the DSH ecosystem, version 1.0.1 in packages, under the MIT License, requires Node >= 20, and is compatible with versions starting from DSH 0.2.2-rc.1. It is only released on GitHub, not published to npm, and the current repository star count is very low.
It has only one settings page, no other interface, no gameplay, and does not generate characters or plots. Functionally, it does three things: read diaries, trigger reviews, and write judgments to the state file. If you build your own plugin marketplace index source, categorize it under memory and add tags like relationship, diary, and companion.
It does not judge for the model, nor does it write the diary body for the user. The basis for judgment is only the diary written by the user themselves; the plugin only cares about the filename and modification time, not what is written in the diary.
Core Mechanism¶
Prerequisite: A 4-Layer Memory Structure is Already Built in the Directory¶
The plugin does not build directories or write the body. The prerequisite is a directory with fixed 4-layer filenames, plus a separate “Who am I.md”:
我的记忆/
├── 我是谁.md
├── 2026-11-01-日记.md
├── 2026-11-02-日记.md
├── 2026-11-03-日记.md
├── 2026-W44-周记.md
├── 2026-10-月记.md
└── 2025-年记.md
Corresponding naming rules:
| Layer | Filename | Description |
|---|---|---|
| Day | YYYY-MM-DD-日记.md |
One per day, original text |
| Week | YYYY-Www-周记.md |
One per week, index |
| Month | YYYY-MM-月记.md |
One per month, index |
| Year | YYYY-年记.md |
One per year, index |
“Who am I.md” is not optional; it carries “who I am now” and “where we are”. Starting from 0.8.0, the format is fixed, and the plugin no longer guesses the naming in the directory. If it encounters an unrecognizable format, the plugin will list it for user confirmation.
5-Step Workflow¶
The plugin has no timer, no background process, and no network requests. The flow is as follows:
- Scan Directory: Divide memory into four layers plus “Who am I” by fixed filenames.
- Compare Time: Compare the modification time of each entry with
lastCheckMsin the state file. Any entry updated counts as new content. - Extract by Layer: Yearly journal 1, monthly journals (last 3 months), weekly journals (last 4 weeks), daily journals (last 7 days) original text, plus “Who am I”. Not all are read.
- Model Judgment: Read the index first, then read the last 7 days of original text, make an independent judgment, and only write to the state file.
- Quiet: The state file records the time, the reminder disappears, waiting for the next memory update.
The triggering judgment conditions can be written as:
任意一篇记忆 mtime > state.lastCheckMs → 提醒(按层列出)
任意一篇记忆 mtime ≤ state.lastCheckMs → 不提醒
The reason for not reading everything is to save tokens. Diaries can reach a volume of tens of thousands of entries a year; reading everything once is tens of thousands of words. Going by index compresses the year to about ten thousand words, once over ten thousand tokens. The comparison given in the README saves about twenty times compared to reading everything.
Step 3 uses DSH’s systemPrompt.section() interface. The reminder text is a piece of ordinary Chinese, and there is a 30-second cache (cacheMs defaults to 30000) for checking, so it doesn’t read the disk every round.
State File¶
The state file is by default placed outside the memory directory:
<diaryDir 的父目录>/.dsh-diary-relation-check/state.json
The content looks like this:
{
"lastCheckMs": 1793707286776,
"verdict": "yes",
"reason": "具体理由",
"relation": { "label": "母子", "status": "confirmed", "since": 1793707286776 }
}
verdict has four levels: yes (Still / Established), not-yet (Not yet), broken (Broken), unsure (Cannot read). relation records confirmed relationships, and status is confirmed or broken.
The design requires that every trigger is an independent judgment: the model cannot read the previous verdict / reason, and cannot rely on it; but relation must be read, as it is needed for review. The judgment result is not written into the diary. If the diary still retains a “Relationship Judgment” section written previously, the reminder explicitly requires skipping it.
For relationships already confirmed, the next reminder switches to a review version, only asking “Did it break?”, with answers only yes / broken; after breaking, the next time returns to the four levels.
Memory Injection per Round¶
In addition to the judgment reminder, the plugin also puts a full “Who am I” and the filenames of the last 7 days of diary entries into the system prompt for every round of conversation (not reading the body, it needs to be opened by the user). This part is unrelated to the judgment; even if the judgment is turned off, it remains and can be disabled with memoryInjection: false. README estimates about 1400 tokens per round based on one page of “Who am I” plus seven filenames, accounting for 0.14% of a 1M window.
Installation and Enablement¶
The repository is only released on GitHub. The installation command is:
dsh plugin --profile web add github:CatisAkaLi/dsh-diary-relation-check
If git is not installed on the machine, the above command will fail (it uses git to resolve the repository). The alternative is to download the repository to any local directory, then:
dsh plugin --profile web add link:<那个目录的绝对路径>
After installation, DSH must be restarted. The plugin module uses ESM caching, and hot updates will not reload. After installation, configuration must be added: the plugin doesn’t know where the memory is, diaryDir is a required field. If not filled, it will report an error in the logs and not work.
Add a section in cordis.patch.yml in the profile:
- insert:
- id: relation-check
name: 'dsh-diary-relation-check'
config:
diaryDir: 'D:\我的记忆'
person: 'ta'
The priority of configuration sources is: cordis.patch.yml in the profile > config.json > defaults. Items overridden by YAML will be marked on the settings page. After saving, it will not automatically restart, only showing “Saved, effective after restarting DSH”.
Uninstallation¶
- Delete the
id: relation-checksection fromcordis.patch.ymlin the profile; - Delete
"dsh-diary-relation-check"fromdsh.profile.bundlesinpackage.json; - Restart DSH.
The plugin does not write anything else in the system; once deleted, it is clean, and memory files are unaffected.
Configuration Items¶
| Config Item | Required | Default | Description |
|---|---|---|---|
diaryDir |
Yes | None | Directory where memory is located |
stateFile |
No | <diaryDir 的父目录>/.dsh-diary-relation-check/state.json |
State file location, intentionally placed outside memory directory by default |
question |
No | 我们现在是什么关系 |
The question to be judged |
questions |
No | 关系向三问 | Ask self-questions one by one before judgment, replace {person} with pronouns; array or string with one per line |
person |
No | ta |
The word used to refer to the other party in the reminder |
self |
No | Empty (let model recognize from diary) | Your role in this relationship |
intimateMode |
No | false |
Intimate mode, manual toggle |
memoryInjection |
No | true |
Include “Who am I” and last 7 days diary filenames each round |
cacheMs |
No | 30000 |
Reminder text cache duration |
order |
No | 900 |
Order of injected prompt section |
autoInit |
No | false |
Auto-create directory and first entry when no diary exists |
initFileName |
No | {{date}}-日记.md |
Filename for auto-created files, replace {{date}} with YYYY-MM-DD |
diaryTemplate |
No | Built-in empty template | What to write in the first entry auto-created |
diaryGuide |
No | true |
Attach “How to remember memory” in reminder; false to disable, string can be customized |
memorySetup |
No | false |
Set up a complete memory structure |
sessionId |
No | Empty (all sessions) | Judgment only appears in this session; memory injection is unaffected |
question can be replaced with any event you want to ask periodically, such as “Should we partner with this person” or “Should this job continue”. The plugin logic remains unchanged: ask periodically, must answer, must give reason.
Relationship types are not preset and are read from the diary. Default pronouns are also not preset; confirm “Who are you, who is the other party” before each judgment. To fix roles, fill in self / person. It should be noted that: AI only recognizes content actually written in the diary; forging diaries can fool the judgment, but that relationship only exists in the file.
How to Verify It Is Working¶
After installing and restarting, check three places in order:
- Settings → Memory Check can be opened, and all three tabs are present. The status page can see the memory directory, the recognized count of day/week/month/year entries; “Will remind now” shows “Yes”, indicating the directory was read and there is new memory compared to the last judgment.
- Modify a diary entry (create a new one or move the modification time of an existing one forward). The system prompt in the next round of conversation should have an extra judgment reminder, starting with “Memory has been updated, read through the layers, then make a judgment”.
- After the model judges, it will overwrite the state file. Go back to the status page to see; “Last Judgment” and “Judgment Result” update accordingly, and “Will remind now” changes to “No”, until the next memory update.
If the settings page is normal but the judgment reminder does not appear, check two points: whether it is registered in dsh.profile.bundles, and whether the modification time of the diary is actually newer than lastCheckMs in the state file.
Suitable Scenarios and Notes¶
Suitable for those who already use DSH + AGENTS.md solutions to maintain .md memory, but want the model to periodically perform an independent judgment on “relationship status”. Its judgment reminder is attached to the system prompt of the conversation, so it is material for companion/conversation scenarios; engineering fact memory (paths, parameters, pitfalls) should still belong to specialized engineering memory plugins; this plugin only touches relationships.
Points to note:
- The plugin runs with the permissions of the current DSH process; check the source code and license (MIT) before deciding whether to enable.
- It does not write the diary body for you, nor does it judge for you; diary quality directly determines judgment quality; a judgment that cannot provide specific reasons will be asked again in the next reminder.
- It does not do database, encryption, or uploading; the main body of memory is still
.mdin the directory, and the state file is outside the directory. - The required directory naming is fixed starting from 0.8.0; if existing memory does not comply, the initialization wizard will provide renaming suggestions and rename after backing up, changing only the filename, not the content.
Directory page: https://www.skillhub.cn/plugins/CatisAkaLi/dsh-diary-relation-check
GitHub: https://github.com/CatisAkaLi/dsh-diary-relation-check