dsh-engramory 0.2.2 → 0.2.5

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.
package/README.md CHANGED
@@ -115,6 +115,16 @@ newline, so an index sitting exactly at the cap stays writable.
115
115
  skill registry). The test mock now mirrors the reflective-context access rules, and
116
116
  the guard's decision table stays covered by `node --test` (28 cases, run in
117
117
  Engramory's CI).
118
+ - **Checked against the dsh you are likely running, not only the one it was written
119
+ on.** `tests/dsh_e2e/run.py` in the Engramory repo installs a dsh release into a
120
+ throwaway prefix, adds this plugin with `dsh plugin add`, and drives one headless
121
+ task against a scripted stand-in for the DeepSeek API: a 260-line write and an edit
122
+ past the cap must come back refused by this guard with nothing reaching the disk, a
123
+ small write must land byte for byte, the skill must be advertised, every tool dsh
124
+ offers must already be classified (a new one could write past the cap), and removal
125
+ must leave a profile that still boots. The releases it passed on are listed in
126
+ `package.json` under `dsh.compatibility.dshReleases`; a unit test rejects a
127
+ `compatible` there without a recorded run of the same plugin version and code.
118
128
  - dsh is a developer preview and its plugin API can change. This plugin deliberately
119
129
  touches only `ctx.tools.guard()` and a reactive `ctx.inject(['skills'], …)` child
120
130
  that registers the skill, so it stays cheap to fix.
package/README.zh-CN.md CHANGED
@@ -103,6 +103,13 @@ dsh plugin --profile <名字> add dsh-engramory
103
103
  内置的 `@deepseek-ai/cordis` 解析器验过(注册表存在、不存在、以及晚挂载三种情况下的激活)。
104
104
  测试用的 mock 现在会照着反射式上下文的访问规则来,守卫的判决表则由 `node --test`
105
105
  持续覆盖(28 个用例,在 Engramory 的 CI 里跑)。
106
+ - **验的是你大概率正在用的 dsh,不只是写它时的那一版。** Engramory 仓库里的
107
+ `tests/dsh_e2e/run.py` 会把指定的 dsh 版本装进临时目录,用 `dsh plugin add` 装上本插件,
108
+ 再对着一个脚本化的 DeepSeek API 替身跑一次 headless 任务:260 行的整文件写入、把索引撑过
109
+ 上限的 edit,都必须被本守卫拒绝,而且磁盘上什么都没变;小写入必须逐字节落盘;skill 必须出现
110
+ 在发给模型的技能目录里;dsh 提供的每个工具都必须已经归过类(没归类的新工具可能绕过上限写文件);卸载后
111
+ profile 必须还能启动。通过的版本逐个写在 `package.json` 的 `dsh.compatibility.dshReleases`
112
+ 里;没有同一插件版本、同一份代码的通过记录,单元测试就不接受把它标成 `compatible`。
106
113
  - dsh 目前是开发者预览版,插件 API 可能变化。本插件刻意只碰 `ctx.tools.guard()` 和一个
107
114
  注册 skill 的响应式 `ctx.inject(['skills'], …)` 子上下文,所以要跟着改也很便宜。
108
115
 
package/index.js CHANGED
@@ -97,11 +97,20 @@ export function apply(ctx, config = {}) {
97
97
  name: 'engramory',
98
98
  description:
99
99
  'Curated file-based long-term memory: recall through MEMORY.md at the start of ' +
100
- 'a task, save durable user/feedback/project/reference facts, and sync before ' +
101
- 'compacting or opening a fresh thread.',
100
+ 'a task, save durable user/feedback/project/reference facts, run a curation ' +
101
+ 'checkpoint when a task finishes, and sync before compacting or opening a ' +
102
+ 'fresh thread. A turn that starts no work — a greeting, an acknowledgement — ' +
103
+ 'is not a task and needs none of this, but never judge that by length: a ' +
104
+ 'one-word reply continuing work underway inherits that task.',
102
105
  whenToUse:
103
106
  'Starting or resuming work, learning something durable worth a future session, ' +
104
- 'or approaching a compact/clear/new-thread boundary.',
107
+ 'finishing a task — including one that leaves nothing worth saving, since the ' +
108
+ 'checkpoint is still a decision to make — or approaching a ' +
109
+ 'compact/clear/new-thread boundary. Not for a bare greeting, ' +
110
+ 'acknowledgement, or reaction, which starts no task — but a terse reply ' +
111
+ 'that continues work underway does, and material already in hand (a ' +
112
+ 'pasted diff to review) does not make work a non-task. Unsure? Treat it ' +
113
+ 'as a task.',
105
114
  source: 'runtime',
106
115
  content: skill,
107
116
  }))
@@ -364,10 +373,23 @@ function builtinSkillBody() {
364
373
  '',
365
374
  'One canonical store: `MEMORY.md` is an index of pointers, one line per memory;',
366
375
  'each fact lives in its own small markdown file beside it. Never put content in',
367
- 'the index, and never keep a second parallel store for handoffs.',
376
+ 'the index, and never keep a second parallel store for handoffs. The ACTIVE',
377
+ 'store is flat — the four type names are values of the `type:` field, not',
378
+ 'subdirectories to create; `archive/` is the one reserved subdirectory, for',
379
+ 'notes retired out of the index.',
368
380
  '',
369
381
  '## Recall',
370
382
  '',
383
+ 'A turn, a message, or a session is NOT BY ITSELF a task: a greeting, an',
384
+ 'acknowledgement, or a reaction starts none, so it gets no recall and no',
385
+ 'checkpoint. A task is user-directed work whose CORRECT handling could depend',
386
+ 'on what the store holds — read-only work (analysis, diagnosis, planning,',
387
+ 'review)',
388
+ 'counts, and changing a file is not required. HAVING THE MATERIAL IN HAND does',
389
+ 'not make work a non-task: a diff pasted for review is still a task. NEVER INFER',
390
+ 'THIS FROM LENGTH: a one-word reply that picks an option or carries on work',
391
+ 'underway inherits that task. Still unclear? Treat it as a task.',
392
+ '',
371
393
  'At the start of a task, read the index and open only the notes whose hooks look',
372
394
  'relevant. Treat what you recall as background that may be stale: re-verify any',
373
395
  'file, flag, or version against the repo before acting on it.',
@@ -398,6 +420,21 @@ function builtinSkillBody() {
398
420
  '"the current version is X", the tip commit, or a passing test count will rot —',
399
421
  'record where to read those instead.',
400
422
  '',
423
+ 'An unfinished task may keep AT MOST ONE live `project` note holding its goal,',
424
+ 'status, decisions, constraints, blockers, and next step together — the single',
425
+ 'exception to one-file-one-fact, and a ceiling rather than a quota: a task that',
426
+ 'needs no resumable state keeps no note. Update it IN PLACE. Never a dated',
427
+ 'series (`state-2026-01-15.md`, `state-2026-01-16.md`, …), never a second',
428
+ 'handoff log indexed beside it, and retire its transient state once it ends.',
429
+ '',
430
+ '## When a task finishes',
431
+ '',
432
+ 'Run one curation checkpoint. It is a judgement, not a write: promote what is',
433
+ 'durable, retire the transient state the CURRENT task left on its own live',
434
+ '`project` note if it has one, and when nothing is worth keeping, write',
435
+ 'nothing and say so. Never append a per-turn log TO THE STORE, and never touch',
436
+ 'a file just to mark it fresh — a timestamp is not a memory.',
437
+ '',
401
438
  '## Sync',
402
439
  '',
403
440
  'Before a deliberate compact, clear, or new thread: scan the task, dedup and update,',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-engramory",
3
- "version": "0.2.2",
3
+ "version": "0.2.5",
4
4
  "description": "Curated file-based long-term memory for DeepSeek Harness — human-readable markdown notes, one plain-file store shared across hosts (git-ignored when it lives inside a project repo), and a deterministic index cap enforced by ctx.tools.guard()",
5
5
  "keywords": [
6
6
  "dsh-plugin",
@@ -17,6 +17,15 @@
17
17
  "dsh": {
18
18
  "bundle": {
19
19
  "patch": "./cordis.patch.yml"
20
+ },
21
+ "compatibility": {
22
+ "dsh": ">=0.1.0-rc.7 <0.2.0-0",
23
+ "dshReleases": {
24
+ "0.1.5-rc.3": "compatible",
25
+ "0.1.7-alpha.1": "compatible",
26
+ "0.1.7-alpha.2": "compatible",
27
+ "0.1.7-rc.1": "compatible"
28
+ }
20
29
  }
21
30
  },
22
31
  "exports": {
@@ -42,14 +51,6 @@
42
51
  "engines": {
43
52
  "node": ">=18"
44
53
  },
45
- "peerDependencies": {
46
- "@deepseek-ai/dsh-tools": ">=0.0.1-rc.1"
47
- },
48
- "peerDependenciesMeta": {
49
- "@deepseek-ai/dsh-tools": {
50
- "optional": false
51
- }
52
- },
53
54
  "publishConfig": {
54
55
  "access": "public"
55
56
  }