dsh-engram 0.5.1 → 0.6.0
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 +118 -39
- package/README.zh.md +101 -40
- package/docs/CONTEXT-GC-GUIDE.zh.md +15 -9
- package/docs/PROPOSAL-evolution.zh.md +684 -0
- package/docs/RELEASE-NOTES-v0.6.0.md +64 -0
- package/lib/api.js +5 -0
- package/lib/boundary-prune.js +27 -1
- package/lib/client.js +88 -2
- package/lib/index.js +165 -18
- package/lib/jit.js +224 -0
- package/lib/ledger.js +458 -0
- package/lib/settings.js +12 -4
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -264,8 +264,8 @@ curl -s -X POST http://127.0.0.1:3080/api/dsh-engram/import \
|
|
|
264
264
|
<!-- dsh-market compatibility block — keep labels bilingual and in sync with
|
|
265
265
|
docs/RELEASE-NOTES.TEMPLATE.md (market README convention) -->
|
|
266
266
|
|
|
267
|
-
- **DSH 版本 / DSH versions**: `>=0.1.2-alpha.2 <0.3.0-0` (本版 `0.
|
|
268
|
-
- **最后验证日期 / Last verified**: 2026-10-19 —
|
|
267
|
+
- **DSH 版本 / DSH versions**: `>=0.1.2-alpha.2 <0.3.0-0` (本版 `0.6.0`; 已发布的 `0.3.7`、`0.4.0` 仍声明旧的 `0.1.x` 范围 `>=0.1.2-alpha.2 <0.2.0-0` — 见下方矩阵)
|
|
268
|
+
- **最后验证日期 / Last verified**: 2026-10-19 — Context Ledger / 默认值纠偏 / JIT 推送,npm test 359/359 通过
|
|
269
269
|
- **安装方式已验证 / Verified install**: `dsh plugin --profile web add dsh-engram`
|
|
270
270
|
|
|
271
271
|
> **Short version.** Every **published** release (`0.2.0` … `0.3.6`) supports
|
|
@@ -280,7 +280,8 @@ curl -s -X POST http://127.0.0.1:3080/api/dsh-engram/import \
|
|
|
280
280
|
| `0.2.0` … `0.3.6` (npm, GitHub v0.3.3–v0.3.6) | published | **old DSH only** — `0.1.0-rc.7` / `0.1.0-rc.8` / `0.1.1-rc.1` / `0.1.1-rc.2` | peers `@deepseek-ai/dsh-*@^0.1.0-rc.7` |
|
|
281
281
|
| `0.3.7` / `0.4.0` (npm) | published | **new DSH, settings `installSection`** — `>=0.1.2-alpha.2 <0.2.0-0` | `engines.dsh` + peers `>=0.1.2-alpha.2 <0.2.0-0` |
|
|
282
282
|
| `0.5.0` (npm) | published | **DSH `0.1.2-alpha.2` … `<0.3.0-0`** — 设置卡迁移到 entry-id volatile Config(`0.1.7+`/`0.2.x`),`≤0.1.5` 自动回退 `installSection` | `engines.dsh` + peers `>=0.1.2-alpha.2 <0.3.0-0` |
|
|
283
|
-
| `0.5.1`
|
|
283
|
+
| `0.5.1` | published | 同 `0.5.0` — 会话扫描修复(`session.v<N>.jsonl.zstd`,issue #8)、数据导出/导入 GUI、替换/冲突可视化(issue #3) | 同 `0.5.0` |
|
|
284
|
+
| `0.6.0` (本期 / this release) | published | 同 `0.5.0` — Context Ledger、BoundaryPrune/ResultPack 默认开 + 账本否决、JIT 推送、Context GC 改 opt-in | 同 `0.5.0` |
|
|
284
285
|
|
|
285
286
|
### Where the API family broke — `0.1.2-alpha.2`
|
|
286
287
|
|
|
@@ -314,7 +315,7 @@ the loader), and the settings form is keyed by the profile entry id (`engram`),
|
|
|
314
315
|
so nothing needs "mounting". `0.5.0` feature-detects the two generations in
|
|
315
316
|
`installEngramSettings`:
|
|
316
317
|
|
|
317
|
-
- DSH `≥0.1.7` / `0.2.x` — the
|
|
318
|
+
- DSH `≥0.1.7` / `0.2.x` — the 31 GUI knobs are the volatile `Config` fields
|
|
318
319
|
(`lib/settings.js` `makeEngineConfigSchema`, exported as `Config` from
|
|
319
320
|
`lib/index.js`); the card reads/writes entry `engram` through the same
|
|
320
321
|
`/api/dsh-engram/settings` HTTP route, and the `service.settings` seam
|
|
@@ -330,14 +331,27 @@ drives mutations).
|
|
|
330
331
|
So: keep DSH on `0.1.1-rc.2` or older while running a release ≤ `0.3.6`, and
|
|
331
332
|
upgrade the plugin to `>=0.3.7` before moving DSH to `0.1.2-alpha.2`.
|
|
332
333
|
|
|
333
|
-
### Current release — `0.
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
334
|
+
### Current release — `0.6.0`
|
|
335
|
+
|
|
336
|
+
From a "memory plugin" to a **context portfolio**: make token savings auditable
|
|
337
|
+
first, then use the ledger to correct defaults, veto unprofitable prunes and
|
|
338
|
+
push memory at deterministic moments.
|
|
339
|
+
|
|
340
|
+
- **Context Ledger** — per session / workspace / day
|
|
341
|
+
`net = avoided − injected − rewrite penalty`; exposed on `/stats` and
|
|
342
|
+
`/overview`, rendered on the telemetry page, persisted to
|
|
343
|
+
`~/.dsh/engram/ledger.json`.
|
|
344
|
+
- **Default correction** — `boundaryPrune` / `resultPack` default ON (pruning is
|
|
345
|
+
lossless via the archive); `gcReplacesCompaction` / `autoWebCompaction` are
|
|
346
|
+
now opt-in (no preset rewriting by default).
|
|
347
|
+
- **Ledger veto** — `boundaryPruneAdaptive` stops pruning a workspace whose own
|
|
348
|
+
accounting is net negative after ≥3 real fires (fail-open).
|
|
349
|
+
- **JIT push** — error recurrence / file focus / goal completion, append-only,
|
|
350
|
+
≤3 lines per session, silent without a hit; `[JIT]` section + `jitEnabled`.
|
|
351
|
+
- **Migration** — restart `dsh web` after upgrading; if you still want Context
|
|
352
|
+
GC takeover, set `gcReplacesCompaction:true` (plus `autoWebCompaction:true`
|
|
353
|
+
for web presets). The `0.5.1` versioned session-log fix (issue #8) and data
|
|
354
|
+
backup GUI (issue #3) are unchanged.
|
|
341
355
|
|
|
342
356
|
The published `0.4.0` declared `>=0.1.2-alpha.2 <0.2.0-0` — which the semver
|
|
343
357
|
gate **rejects on every DSH `0.2.0-0` prerelease** (`<0.2.0-0` excludes
|
|
@@ -358,7 +372,7 @@ feature-detected legacy fallback).
|
|
|
358
372
|
`0.1.2-alpha.2` is the minimum version for this API family: host settings are
|
|
359
373
|
**feature-detected** — on DSH `≤0.1.5` they register the `dsh-engram`
|
|
360
374
|
namespace via `settings.installSection`; on `≥0.1.7` / `0.2.x` the form is the
|
|
361
|
-
plugin's `Config` with the
|
|
375
|
+
plugin's `Config` with the 31 GUI knobs marked `.volatile()` (entry id
|
|
362
376
|
`engram`). The browser settings card reads and writes through the plugin's own
|
|
363
377
|
HTTP route (`/api/dsh-engram/settings`, see Route B above) on both. The full
|
|
364
378
|
regression suite (npm test 329/329, incl. the new settings-v2 coverage for the
|
|
@@ -623,10 +637,12 @@ Triggers follow DSH's own compaction timing (step pressure / context-overflow /
|
|
|
623
637
|
`/compact`); the lock, replay validation, tool-call/result pairing and token
|
|
624
638
|
pricing are all reused from the basic engine. Any error falls back to the
|
|
625
639
|
default compressor — compaction is never broken; with `gcReplacesCompaction:
|
|
626
|
-
false` (or a host without `dsh-compaction-basic`) a bare
|
|
627
|
-
is mounted instead, so the `compaction` service never
|
|
628
|
-
dsh-engram is installed. Mounting registers the `compaction`
|
|
629
|
-
plugin's fiber, so unloading/reloading engram restores the
|
|
640
|
+
false` (the default since v0.6, or a host without `dsh-compaction-basic`) a bare
|
|
641
|
+
`BasicCompactionEngine` is mounted instead, so the `compaction` service never
|
|
642
|
+
disappears while dsh-engram is installed. Mounting registers the `compaction`
|
|
643
|
+
service on the plugin's fiber, so unloading/reloading engram restores the
|
|
644
|
+
default engine. **Taking over compaction is opt-in**: turn on
|
|
645
|
+
`gcReplacesCompaction` (and `autoWebCompaction` for web presets).
|
|
630
646
|
|
|
631
647
|
> **Shrink gate**: the harness refuses any checkpoint that is not strictly
|
|
632
648
|
> smaller than the evicted span (`summary is not smaller than the shadowed
|
|
@@ -641,19 +657,19 @@ plugin's fiber, so unloading/reloading engram restores the default engine.
|
|
|
641
657
|
|
|
642
658
|
#### Where it is enabled (the entry point)
|
|
643
659
|
|
|
644
|
-
Assembly happens on **two planes
|
|
660
|
+
Assembly happens on **two planes**, but both switches are opt-in (no takeover by
|
|
661
|
+
default):
|
|
645
662
|
|
|
646
|
-
- **Host plane (headless / TUI / base profiles)
|
|
663
|
+
- **Host plane (headless / TUI / base profiles)**:
|
|
647
664
|
the main plugin (`lib/index.js`) mounts the engine inside `ctx.effect` via
|
|
648
665
|
`mountCompactionEngine(ctx, resolved, { readWorkspace }) → new Engine()`,
|
|
649
666
|
registering the `compaction` service on its own fiber; the plugin patch
|
|
650
667
|
disables the base `compaction-basic` row, making engram the sole host-plane
|
|
651
|
-
provider. `gcReplacesCompaction:
|
|
652
|
-
`
|
|
653
|
-
(
|
|
654
|
-
`
|
|
655
|
-
- **Preset plane (web profile) —
|
|
656
|
-
preset**: web keeps compaction inside each agent preset's isolated realm
|
|
668
|
+
provider. `gcReplacesCompaction: false` (default) → a bare
|
|
669
|
+
`BasicCompactionEngine` (DSH's own summarizer); `true` → `ContextGcEngine`
|
|
670
|
+
(pointer summaries). Enable via profile patch
|
|
671
|
+
(`config: { gcReplacesCompaction: true }`) or the settings card.
|
|
672
|
+
- **Preset plane (web profile) — covers every stock preset once enabled**: web keeps compaction inside each agent preset's isolated realm
|
|
657
673
|
(the shipped presets mount their own `compaction-basic`), unreachable from a
|
|
658
674
|
host-plane row — and unreachable from a profile patch too (`mountPreset`
|
|
659
675
|
builds its `Include.Config` with no patches; verified against the harness
|
|
@@ -663,8 +679,9 @@ Assembly happens on **two planes** — and web is now fully automatic, zero conf
|
|
|
663
679
|
root: `standard`, `code`, `cordis`, and your own presets): it swaps the
|
|
664
680
|
`compaction-basic` row inside the `compaction` group for
|
|
665
681
|
`dsh-engram/compaction`. That auto-wiring is:
|
|
666
|
-
- **
|
|
667
|
-
memory-GC section)
|
|
682
|
+
- **off by default (opt-in)** (`autoWebCompaction: false`, toggle in the
|
|
683
|
+
settings card's memory-GC section); once enabled it is idempotent — an
|
|
684
|
+
already-wired preset is left alone;
|
|
668
685
|
**what "off" means**: the plugin stops auto-wiring on later boots (the
|
|
669
686
|
headless/TUI/base host plane is unaffected) — it does NOT un-wire presets
|
|
670
687
|
that were already wired; use `npm run web-compaction:revert` for that;
|
|
@@ -719,9 +736,10 @@ Assembly happens on **two planes** — and web is now fully automatic, zero conf
|
|
|
719
736
|
|
|
720
737
|
#### First impressions after an npm install (perceive / guide / configure)
|
|
721
738
|
|
|
722
|
-
- **
|
|
723
|
-
|
|
724
|
-
|
|
739
|
+
- **Semi-automatic (opt-in)**: DSH's own summarizer stays the default. Turn on
|
|
740
|
+
`gcReplacesCompaction` (host plane) and `autoWebCompaction` (web presets) in
|
|
741
|
+
the settings card, then boot once — `mountCompactionEngine` takes over and
|
|
742
|
+
the stock presets are rewritten. **No file editing after that.**
|
|
725
743
|
- **Perceivable**: at boot the plugin writes an authoritative snapshot to
|
|
726
744
|
`$DSH_HOME/engram/context-gc.status.json` (`host` plane mode + the per-preset
|
|
727
745
|
`web` results + effective config). At any time run `npx dsh-engram status` or
|
|
@@ -730,8 +748,9 @@ Assembly happens on **two planes** — and web is now fully automatic, zero conf
|
|
|
730
748
|
log lines confirm it too: `engram context-gc: compaction = Context GC …` and
|
|
731
749
|
`engram web-provision: wired Context GC into preset …`.
|
|
732
750
|
- **Configurable**: one settings card (memory-GC section) governs everything:
|
|
733
|
-
`autoWebCompaction` (web auto-wiring
|
|
734
|
-
(Context GC vs default
|
|
751
|
+
`autoWebCompaction` (web auto-wiring, default off), `gcReplacesCompaction`
|
|
752
|
+
(Context GC vs host summarizer, default off), `gcNarrative` (narrative
|
|
753
|
+
safety net).
|
|
735
754
|
Changes take effect after restarting `dsh web`, and the web rows are
|
|
736
755
|
refreshed to match automatically.
|
|
737
756
|
|
|
@@ -748,7 +767,7 @@ means that preset was customized (or has no compaction group) and was left untou
|
|
|
748
767
|
`dsh-compaction-basic unavailable` means the backend is missing and everything
|
|
749
768
|
falls back to the default compressor.
|
|
750
769
|
|
|
751
|
-
### BoundaryPrune (subtask-boundary pruning, default
|
|
770
|
+
### BoundaryPrune (subtask-boundary pruning, default ON + ledger veto)
|
|
752
771
|
|
|
753
772
|
Context GC owns *what a compaction summary says*; BoundaryPrune owns *when a
|
|
754
773
|
deterministic prune fires*: at todo-completion progress and goal terminal
|
|
@@ -783,10 +802,13 @@ later request. The two switches are independent.
|
|
|
783
802
|
T2048+small-edges lands 2.4× the first-prune savings of the host default on
|
|
784
803
|
the real corpus (10.14M vs 4.23M chars). Lowering the threshold is safe with
|
|
785
804
|
`resultPack` on, which archives the removed middles.
|
|
786
|
-
- Default **
|
|
805
|
+
- Default **on**: `boundaryPrune: true` (`false` is the opt-out). Adaptive gate
|
|
806
|
+
`boundaryPruneAdaptive: true` lets the Context Ledger stop further fires once
|
|
807
|
+
this workspace's own accounting is net negative (≥3 fires) — evidence can only
|
|
808
|
+
turn pruning off. The log shows
|
|
787
809
|
`engram boundary-prune (todo @N reqs): pruned …`.
|
|
788
810
|
|
|
789
|
-
### ResultPack L2 (archive + `result_recall`, default
|
|
811
|
+
### ResultPack L2 (archive + `result_recall`, default ON)
|
|
790
812
|
|
|
791
813
|
BoundaryPrune makes pruning lossless: the removed middle of every pruned
|
|
792
814
|
tool result is redacted (same rules as the memory write path) and archived to
|
|
@@ -824,6 +846,58 @@ Mechanisms must be provably activating, and dormant ones are off by default.
|
|
|
824
846
|
the loop already measured from session logs (engram_recall queries → hits →
|
|
825
847
|
engram_detail follows) so you can see injection→query→detail activation.
|
|
826
848
|
|
|
849
|
+
### Context Ledger (net-savings accounting)
|
|
850
|
+
|
|
851
|
+
Turns "saves tokens" into a checkable number. Every model request is one ledger
|
|
852
|
+
tick: injected `[ENGRAM]`/`[RECALL]` and `[ESR]` blocks are charged per request
|
|
853
|
+
they survive; results removed by BoundaryPrune are credited per later request
|
|
854
|
+
they no longer replay; every prune pays one prefix-rewrite penalty
|
|
855
|
+
`(1 − ledgerCacheDiscount)` (the KV-cache break). `GET /api/dsh-engram/stats`
|
|
856
|
+
and `/overview` return `ledger`:
|
|
857
|
+
|
|
858
|
+
- `totals` — `requests / injectedChars / avoidedChars / rewriteCount /
|
|
859
|
+
rewriteChars / netChars / netTokens` with
|
|
860
|
+
`net = avoided − injected − rewriteChars × (1 − discount)`;
|
|
861
|
+
- `byWorkspace` / `byDay` — the same arithmetic per workspace and calendar day
|
|
862
|
+
(`byDay` newest first);
|
|
863
|
+
- `openSessions` — sessions still accumulating in memory (a restart loses at
|
|
864
|
+
most `flushEvery` requests).
|
|
865
|
+
|
|
866
|
+
The Telemetry tab renders it directly (net-token headline, saved / injected /
|
|
867
|
+
rewrite-penalty cards, a 14-day red/green net chart), and the memory overview
|
|
868
|
+
adds a "net context tokens" stat card. Durable rollup at
|
|
869
|
+
`~/.dsh/engram/ledger.json` (atomic write, daily buckets, delta flush); the hot
|
|
870
|
+
path is an integer add, zero I/O and zero model calls.
|
|
871
|
+
Defaults: `ledgerEnabled: true`, `ledgerCacheDiscount: 0.1`; off = no listeners,
|
|
872
|
+
no writes. **Honest scope**: tokens are `chars / 4` estimates, not provider
|
|
873
|
+
billing, and no quality delta is claimed; Context GC compaction savings are not
|
|
874
|
+
wired yet (the host does not expose before/after sizes), so the ledger only
|
|
875
|
+
counts what it can prove.
|
|
876
|
+
|
|
877
|
+
### JIT push (v0.6-C)
|
|
878
|
+
|
|
879
|
+
Pull-only recall measured dormant (24 `engram_recall` / 8 `engram_detail` across
|
|
880
|
+
112 real sessions), so v0.6 pushes on three deterministic events instead. One
|
|
881
|
+
line per event, at most 3 lines per session (`jitMaxLines`, `jitMaxLineChars`=220),
|
|
882
|
+
and silence when there is nothing relevant to point at:
|
|
883
|
+
|
|
884
|
+
| Event | Trigger | What is pushed |
|
|
885
|
+
|---|---|---|
|
|
886
|
+
| Error recurrence | the same `cmd:` signature fails a second time and a prior error/procedure memory exists | that memory's id + a one-line excerpt + `engram_detail` |
|
|
887
|
+
| File focus | the same file is edited twice in a row and a filePath/dir-anchored memory exists | preference first, then fact/decision |
|
|
888
|
+
| Goal completion | goal complete/block while active ESR tasks remain | the first two open tasks + `esr_status` |
|
|
889
|
+
|
|
890
|
+
- **Append-only**: a pushed line is never edited or withdrawn, so the prefix
|
|
891
|
+
changes once per push. Each push charges a rewrite
|
|
892
|
+
(`estimatePrefixChars + line length`) in the Context Ledger
|
|
893
|
+
(`rewriteCount` / `rewriteChars`), visible on the telemetry page.
|
|
894
|
+
- **Silent without a hit** — no memory/task to point at, no line.
|
|
895
|
+
- **Zero LLM, pure rules**; `jitEnabled:false` disables it, and the empty
|
|
896
|
+
`[JIT]` section costs nothing.
|
|
897
|
+
- **Not yet**: the resume brief (next-day continuation) and an explicit
|
|
898
|
+
remaining-requests ROI gate — today the 3-line budget plus the ledger are the
|
|
899
|
+
guardrails.
|
|
900
|
+
|
|
827
901
|
## Auto-capture policy
|
|
828
902
|
|
|
829
903
|
Capture is deterministic and offline — it only sees tool *results*, never the
|
|
@@ -908,12 +982,13 @@ Defaults are token-conscious; override any key via the profile patch
|
|
|
908
982
|
autoCapture: true # zero-LLM tool-result capture
|
|
909
983
|
autoCapturePreferences: true # zero-LLM user-correction/preference capture (prefer/avoid/switch-to cues)
|
|
910
984
|
preferenceCapturePerSession: 8 # per-session preference memory cap
|
|
911
|
-
boundaryPrune:
|
|
985
|
+
boundaryPrune: true # ResultPack L1: prune stale over-threshold tool results at todo/goal boundaries (default ON)
|
|
986
|
+
boundaryPruneAdaptive: true # ledger veto: stop pruning this workspace once its net is negative (>=3 fires)
|
|
912
987
|
boundaryPruneThresholdChars: 0 # threshold override (0 = host 8192; e.g. 2048 prunes earlier)
|
|
913
988
|
boundaryPruneHeadChars: 0 # retained head under an override (0 = host 4096)
|
|
914
989
|
boundaryPruneTailChars: 0 # retained tail under an override (0 = host 1024)
|
|
915
990
|
boundaryPruneIdleCadence: 0 # request-count boundary for todo/goal-less sessions (0 = event-only)
|
|
916
|
-
resultPack:
|
|
991
|
+
resultPack: true # ResultPack L2: archive pruned middles + result_recall paged recall (default ON; needs L1 on)
|
|
917
992
|
resultPackRetentionDays: 7 # archive retention days (mtime sweep on the GC cadence)
|
|
918
993
|
sessionSearch: true # engram_recall may also FTS past sessions
|
|
919
994
|
recallScope: workspace # recall scope: "workspace" (strict isolation, default) | "global" (opt-in cross-workspace recall with [W:<ws>] origin markers)
|
|
@@ -932,8 +1007,12 @@ Defaults are token-conscious; override any key via the profile patch
|
|
|
932
1007
|
gcEnabled: true # scheduled memory GC
|
|
933
1008
|
gcIntervalHours: 24 # sweep cadence
|
|
934
1009
|
gcStableRetentionDays: 120 # stable tasks leave [ESR] after this
|
|
935
|
-
gcReplacesCompaction:
|
|
1010
|
+
gcReplacesCompaction: false # Context GC: take over DSH auto-compact (default off = host summarizer; true = opt-in pointers)
|
|
936
1011
|
gcNarrative: true # scoped LLM narrative for un-provenanced turns; false = fully mechanical (zero LLM)
|
|
1012
|
+
autoWebCompaction: false # rewrite stock web presets (default off; explicit opt-in, revert with the CLI)
|
|
1013
|
+
jitEnabled: true # JIT push: error recurrence / file focus / goal completion → one memory line
|
|
1014
|
+
ledgerEnabled: true # Context Ledger: injected cost / prune savings / rewrite penalty → net tokens
|
|
1015
|
+
ledgerCacheDiscount: 0.1 # cached-prefix price share; rewrites pay (1−discount)
|
|
937
1016
|
engramIndexOrder: 40 # systemPrompt section order (before tools band)
|
|
938
1017
|
esrOrder: 41
|
|
939
1018
|
```
|
|
@@ -941,7 +1020,7 @@ Defaults are token-conscious; override any key via the profile patch
|
|
|
941
1020
|
## Development
|
|
942
1021
|
|
|
943
1022
|
```sh
|
|
944
|
-
npm test #
|
|
1023
|
+
npm test # 359 tests: core + web API + GC + usage-observability + Context GC + ESR triggers + BoundaryPrune + preference learning + Context Ledger + JIT push (node:test)
|
|
945
1024
|
npm run eval # offline recall + structure benchmark (deterministic)
|
|
946
1025
|
npm run build:client
|
|
947
1026
|
```
|
package/README.zh.md
CHANGED
|
@@ -85,7 +85,7 @@
|
|
|
85
85
|
- **记忆 GC(pi-esr 约束)** — 定时、机械、只归档的回收:TTL 过期记忆归档、超容量工作区淘汰低价值条目、
|
|
86
86
|
stable 任务超保留窗离开 `[ESR]` 表面、悬空链接边清理。工作集(active 任务引用 / 任务记忆 / 已入索引命中)
|
|
87
87
|
永不触碰;**不硬删任何东西**——归档条目保留 id、始终可重取。
|
|
88
|
-
- **Context GC(自动 GC = 替代 DSH 自动 compact)** — 不是记忆面板 GC
|
|
88
|
+
- **Context GC(自动 GC = 替代 DSH 自动 compact,opt-in)** — 不是记忆面板 GC:开启后接管 DSH 自带的上下文压缩
|
|
89
89
|
(`compaction` 服务),把「有损 LLM 全量摘要」换成**机械驱逐 + 重取指针**——扫描被驱逐轮次里的
|
|
90
90
|
engram/ESR 锚(`#记忆id`、`tsk_*`、`ent_*`、`file_path`),只留一行「细节在 `engram_detail` /
|
|
91
91
|
`engram_recall` / `[ESR]` 里」;只有无锚轮次才走 scoped LLM 叙事兜底(`gcNarrative`,默认开、可关成纯机械)。
|
|
@@ -166,8 +166,8 @@ curl -s -X POST http://127.0.0.1:3080/api/dsh-engram/import \
|
|
|
166
166
|
|
|
167
167
|
<!-- dsh-market 兼容信息块 —— 与 docs/RELEASE-NOTES.TEMPLATE.md 的市场 README 公约保持一致 -->
|
|
168
168
|
|
|
169
|
-
- **DSH 版本**:`>=0.1.2-alpha.2 <0.3.0-0`(本版 `0.
|
|
170
|
-
- **最后验证日期**:2026-10-19 ——
|
|
169
|
+
- **DSH 版本**:`>=0.1.2-alpha.2 <0.3.0-0`(本版 `0.6.0`;已发布的 `0.3.7`、`0.4.0` 仍声明旧的 `0.1.x` 范围 `>=0.1.2-alpha.2 <0.2.0-0` —— 见下文矩阵)
|
|
170
|
+
- **最后验证日期**:2026-10-19 —— Context Ledger / 默认值纠偏 / JIT 推送,npm test 359/359 通过
|
|
171
171
|
- **安装方式已验证**:`dsh plugin --profile web add dsh-engram`
|
|
172
172
|
|
|
173
173
|
> **一句话结论**:所有**已真正发布**的版本(`0.2.0` … `0.3.6`)**只支持旧版
|
|
@@ -180,7 +180,8 @@ curl -s -X POST http://127.0.0.1:3080/api/dsh-engram/import \
|
|
|
180
180
|
| `0.2.0` … `0.3.6`(npm 全量 + GitHub v0.3.3–v0.3.6) | 已发布 | **仅旧版** —— `0.1.0-rc.7` / `0.1.0-rc.8` / `0.1.1-rc.1` / `0.1.1-rc.2` | peers `@deepseek-ai/dsh-*@^0.1.0-rc.7` |
|
|
181
181
|
| `0.3.7` / `0.4.0`(npm) | 已发布 | **新版 DSH,settings `installSection`** —— `>=0.1.2-alpha.2 <0.2.0-0` | `engines.dsh` + peers 同范围 |
|
|
182
182
|
| `0.5.0`(npm) | 已发布 | **DSH `0.1.2-alpha.2` … `<0.3.0-0`** —— 设置卡迁移到 entry-id volatile Config(`0.1.7+`/`0.2.x`),`≤0.1.5` 自动回退 `installSection` | `engines.dsh` + peers `>=0.1.2-alpha.2 <0.3.0-0` |
|
|
183
|
-
| `0.5.1
|
|
183
|
+
| `0.5.1` | 已发布 | 同 `0.5.0` —— 会话扫描修复(`session.v<N>.jsonl.zstd`,issue #8)、数据导出/导入 GUI、替换/冲突可视化(issue #3) | 同 `0.5.0` |
|
|
184
|
+
| `0.6.0`(本期 / this release) | 已发布 | 同 `0.5.0` —— Context Ledger、BoundaryPrune/ResultPack 默认开 + 账本否决、JIT 推送、Context GC 改 opt-in | 同 `0.5.0` |
|
|
184
185
|
|
|
185
186
|
### API 族断裂点:`0.1.2-alpha.2`
|
|
186
187
|
|
|
@@ -207,7 +208,7 @@ HTTP 路由(`/api/dsh-engram/settings`,与记忆 viewer 同样的同源 fetc
|
|
|
207
208
|
profile 条目 id(`engram`)为命名空间,不再需要任何“挂载”调用。`0.5.0`
|
|
208
209
|
在 `installEngramSettings` 里对两代际做特性检测:
|
|
209
210
|
|
|
210
|
-
- DSH `≥0.1.7` / `0.2.x` ——
|
|
211
|
+
- DSH `≥0.1.7` / `0.2.x` —— 31 个 GUI 旋钮即 `Config` 的 volatile 字段
|
|
211
212
|
(`lib/settings.js` `makeEngineConfigSchema`,由 `lib/index.js` 导出为
|
|
212
213
|
`Config`);卡片仍走同一 `/api/dsh-engram/settings` HTTP 路由读写条目 `engram`,
|
|
213
214
|
`service.settings` 接缝在 `loader/volatile-update` 事件上把 `resolved`
|
|
@@ -220,13 +221,23 @@ profile 条目 id(`engram`)为命名空间,不再需要任何“挂载”
|
|
|
220
221
|
所以:跑 ≤ `0.3.6` 的已发布版本时请把 DSH 保持在 `0.1.1-rc.2` 或更旧;升级
|
|
221
222
|
DSH 到 `0.1.2-alpha.2` 之前,先升级插件到 `>=0.3.7`。
|
|
222
223
|
|
|
223
|
-
### 当前发布版本 —— `0.
|
|
224
|
+
### 当前发布版本 —— `0.6.0`
|
|
224
225
|
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
226
|
+
从「记忆插件」转向**上下文投资组合**:先把省 token 变成可审计的账本,再用账本
|
|
227
|
+
纠正默认值、否决不划算的剪枝,并按确定性事件把记忆推给模型。
|
|
228
|
+
|
|
229
|
+
- **Context Ledger**:每会话/工作区/天记录 `net = 节省 − 注入 − 重写罚金`,
|
|
230
|
+
`/stats` 与 `/overview` 返回,GUI 遥测页有面板;落盘 `~/.dsh/engram/ledger.json`。
|
|
231
|
+
- **默认值纠偏**:`boundaryPrune` / `resultPack` 默认开(剪枝由归档兜底),
|
|
232
|
+
`gcReplacesCompaction` / `autoWebCompaction` 改 opt-in(不再主动改写宿主预设)。
|
|
233
|
+
- **账本否决**:`boundaryPruneAdaptive` 在某 workspace 净收益为负且 ≥3 次剪枝时
|
|
234
|
+
自动停剪(fail-open)。
|
|
235
|
+
- **JIT 推送**:错误复发 / 文件焦点 / goal 完成三类事件,append-only、每会话 ≤3 行、
|
|
236
|
+
无命中沉默;`[JIT]` section + `jitEnabled`。
|
|
237
|
+
- **迁移**:升级后重启 `dsh web`;若仍要 Context GC 接管,显式打开
|
|
238
|
+
`gcReplacesCompaction:true`(web 还需 `autoWebCompaction:true`)。
|
|
239
|
+
- `0.5.1` 的会话日志版本化修复(`session.v<N>.jsonl.zstd`,issue #8)与数据备份
|
|
240
|
+
GUI(issue #3)保持不变。
|
|
230
241
|
|
|
231
242
|
已发布的 `0.4.0` 声明 `>=0.1.2-alpha.2 <0.2.0-0`——这个范围被 semver 门槛在
|
|
232
243
|
**所有 DSH `0.2.0-0` 预发布**上拒绝(`<0.2.0-0` 排除 `0.2.0-rc.x`),且其宿主设置端
|
|
@@ -244,13 +255,13 @@ Config** 模型(并带特性检测的旧代际回退)。
|
|
|
244
255
|
|
|
245
256
|
`0.1.2-alpha.2` 是这组 API 的最低版本:宿主设置注册按代际**特性检测**——DSH `≤0.1.5`
|
|
246
257
|
走 `settings.installSection` 注册 `dsh-engram` 命名空间;`≥0.1.7` / `0.2.x` 走插件
|
|
247
|
-
`Config`(
|
|
258
|
+
`Config`(31 个 GUI 旋钮标记为 `.volatile()`,条目 id `engram`)。浏览器设置卡在两代际
|
|
248
259
|
都经插件自有 HTTP 路由(`/api/dsh-engram/settings`,见上文 Route B)读写。完整回归
|
|
249
260
|
(npm test 329/329,含新增的 volatile-Config 模型 settings-v2 覆盖)在 DSH
|
|
250
261
|
`0.2.0-rc.2` 依赖集(cordis 4.0.4 + schemastery 3.18.4 + cosmokit,与全局 DSH CLI 同版本)
|
|
251
262
|
上通过;`.volatile()`/loader 热提交路径与 describe 侧投影已针对真实 `dsh-settings
|
|
252
263
|
0.2.0-rc.2` 工具函数验证;并在隔离的 `dsh 0.2.0-rc.2` profile 上完成了**真机启动烟测并
|
|
253
|
-
通过**:插件启动无版本范围拒绝、设置卡表单以条目 `engram` 对外提供(全部
|
|
264
|
+
通过**:插件启动无版本范围拒绝、设置卡表单以条目 `engram` 对外提供(全部 31 个 GUI
|
|
254
265
|
旋钮,含 `trustedHosts`)、`/api/dsh-engram/settings` 的 GET → PUT(mutate ops,
|
|
255
266
|
revision 0→1)→ unset 往返落盘并读回。旧的 `0.1.0-rc.7` 与 `0.1.1` API 图不在
|
|
256
267
|
本发布版本的兼容范围内。
|
|
@@ -340,6 +351,7 @@ node scripts/setup-links.mjs # 把 @deepseek-ai 工作区包软链进 node_m
|
|
|
340
351
|
纯 SVG 实现(无图表库,保持 bundle 纯净)。
|
|
341
352
|
以及一个 **遥测仪表盘** 页签:把 /stats 的真实调用累计(工作区 × 天滚动)画成纯 SVG 仪表盘——三枚大圆环
|
|
342
353
|
直读 **ESR 主动性**(与 escalate 阈值 0.34 比对,偏低标橙并提示)、**召回命中率**、**detail 转化**,
|
|
354
|
+
外加一块 **Context Ledger** 面板(净 token、节省/注入/重写罚金三卡、近 14 天净收益红绿柱),
|
|
343
355
|
五张小指标卡(累计调用 / esr / 记忆 / 平均命中每查询 / 失败),近 14 天 mem-vs-esr 堆叠柱状图 +
|
|
344
356
|
工具调用 Top 8 横向条形图(mem 蓝 / esr 紫,与全文配色一致),20s 自动刷新,样本不足(<10 次)自动标注。
|
|
345
357
|
以及 **详情侧栏**(主从布局):任务 / 记忆 / 节点 / 关系行都可一键在右侧打开详情卡——任务含
|
|
@@ -356,7 +368,7 @@ node scripts/setup-links.mjs # 把 @deepseek-ai 工作区包软链进 node_m
|
|
|
356
368
|
面板同时列出各工具调用计数与最近 14 天逐日滚动。这些是真实会话的真实数字——想提升 ESR 主动性,
|
|
357
369
|
就观察面板上 esr 占比并调整注入提示。
|
|
358
370
|
- **设置 → 插件 → 插件配置 → dsh-engram** — 与内置「终端 / Agent 循环 / 网页搜索」同款的
|
|
359
|
-
**默认折叠卡片**:标题 + 一行描述 +
|
|
371
|
+
**默认折叠卡片**:标题 + 一行描述 + 箭头,点击展开/收起;展开后常用 11 项 + 高级分组按
|
|
360
372
|
「捕获与检索 / 索引 / 生命周期与 GC / 安全」四个分组展示。改动对新建会话即时生效
|
|
361
373
|
(已冻结的块保持稳定);支持放弃修改 / 保存,有未保存改动时标题上出现「未保存」徽标。
|
|
362
374
|
卡片通过连接自身的 settings RPC 直连命名空间(不走 isLoopback 门控的 scope),因此即使
|
|
@@ -380,7 +392,7 @@ npm run build:client
|
|
|
380
392
|
## 测试与评测
|
|
381
393
|
|
|
382
394
|
```sh
|
|
383
|
-
npm test #
|
|
395
|
+
npm test # 359 项单元测试(含 usage 滚动 / /stats 路由 / Context GC / ESR 触发 / BoundaryPrune / Context Ledger / JIT 推送)
|
|
384
396
|
npm run eval # 离线召回 + 结构基准(确定性语料,跑真实 store/recall 路径)
|
|
385
397
|
```
|
|
386
398
|
|
|
@@ -438,7 +450,7 @@ GC 永不触碰工作集:active 任务 `memory_refs` 引用的记忆、task
|
|
|
438
450
|
(`hits >= promoteHits`)。用 `esr_gc` + `dry_run: true` 先预览。**不硬删**——报告的末尾为所有
|
|
439
451
|
归档项附上重取指针,归档可恢复、不是丢失。
|
|
440
452
|
|
|
441
|
-
### Context GC(替换 DSH 自动 compact)
|
|
453
|
+
### Context GC(替换 DSH 自动 compact,opt-in)
|
|
442
454
|
|
|
443
455
|
DSH 默认的上下文压缩是**有损 LLM 全量摘要**(`compaction-basic`):被驱逐的历史被压缩成散文,
|
|
444
456
|
不可查询、摘要本身还烧 token。dsh-engram 的自动 GC 替代它:`ContextGcEngine extends
|
|
@@ -453,7 +465,9 @@ BasicCompactionEngine` 只重写唯一的 `summarize()` 钩子,把摘要正文
|
|
|
453
465
|
|
|
454
466
|
触发时机完全跟随 DSH 现有 compact(step pressure / context-overflow / `/compact`);锁、回放校验、
|
|
455
467
|
tool-call/result 配对、token 定价全部复用基本引擎。任何错误 → 回退默认压缩,**永不破坏 compact**。
|
|
456
|
-
装配即注册 `compaction` 服务,卸载/reload engram
|
|
468
|
+
装配即注册 `compaction` 服务,卸载/reload engram 自动还回默认引擎。**自 v0.6 起默认不接管**:
|
|
469
|
+
默认挂裸 `BasicCompactionEngine`(宿主 LLM 摘要),要换成指针摘要需显式打开
|
|
470
|
+
`gcReplacesCompaction`(web 预设还需 `autoWebCompaction`)。
|
|
457
471
|
|
|
458
472
|
> **收缩闸门(shrink gate)**:harness 拒绝任何不比被驱逐片段更小的 checkpoint(`summary is not
|
|
459
473
|
> smaller than the shadowed content`),否则压缩回滚、上下文永不缩小、最终触发模型侧溢出。Context GC
|
|
@@ -464,24 +478,23 @@ tool-call/result 配对、token 定价全部复用基本引擎。任何错误
|
|
|
464
478
|
|
|
465
479
|
#### 启用入口(这一节就是答案:该功能开在哪)
|
|
466
480
|
|
|
467
|
-
Context GC
|
|
481
|
+
Context GC 的装配在**两个平面**,但两个开关都是 opt-in(默认不接管):
|
|
468
482
|
|
|
469
483
|
- **host 平面(headless / TUI / base 型 profile)——开箱即用,无需任何配置**:
|
|
470
484
|
主插件 `lib/index.js` 在 `ctx.effect` 里直接
|
|
471
485
|
`mountCompactionEngine(ctx, resolved, { readWorkspace }) → new Engine()` 注册 `compaction` 服务;
|
|
472
486
|
配合插件 patch 禁用基座 `compaction-basic` 行,engram 即为该平面唯一 provider。
|
|
473
|
-
- `gcReplacesCompaction:
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
-
|
|
477
|
-
|
|
478
|
-
- **preset 平面(web profile)——全自动,零配置,覆盖全部预设**:web 面把 compaction 放在 agent
|
|
487
|
+
- `gcReplacesCompaction: false`(**默认**)→ 挂裸 `BasicCompactionEngine`(DSH 默认 LLM 摘要),
|
|
488
|
+
**`compaction` 服务永不缺席**;
|
|
489
|
+
- `gcReplacesCompaction: true` → `ContextGcEngine`(机械驱逐 + 重取指针,opt-in);
|
|
490
|
+
- 开启:profile patch 里给 engram 行加 `config: { gcReplacesCompaction: true }`,或在设置卡打开。
|
|
491
|
+
- **preset 平面(web profile)——显式开启后覆盖全部 stock 预设**:web 面把 compaction 放在 agent
|
|
479
492
|
preset 的 isolate realm(shipped 预设自挂 `compaction-basic`),host 条目进不去、profile patch 也
|
|
480
493
|
够不到预设文件(`mountPreset` 的 Include 不带 patches——已对源码核实)。所以插件在启动时
|
|
481
494
|
(`agentPresets` 服务就绪后)**自动改写每个仍处于出厂 stock 布局的预设**——默认预设 + 整张 roster
|
|
482
495
|
(shipped 根 + `~/.dsh/.agent-presets` 用户根,`standard`/`code`/`cordis` 和你自己的预设都覆盖):
|
|
483
496
|
把 `compaction` 组里的 `compaction-basic` 行换成 `dsh-engram/compaction`。这一自动装配是:
|
|
484
|
-
-
|
|
497
|
+
- **默认关(opt-in)**(`autoWebCompaction: false`;设置卡「记忆 GC」可开),开启后幂等——已替换则跳过;
|
|
485
498
|
**关掉的含义**:只是在之后的启动时不再自动接管(headless/TUI/base 的 host 平面不受影响)——
|
|
486
499
|
它**不会**还原之前已接管的预设,要还原用 `npm run web-compaction:revert`;
|
|
487
500
|
- **逐预设判定,只碰 stock 布局**——用户自定义过 compaction 组的预设,以及根本没有 compaction 组的
|
|
@@ -527,15 +540,16 @@ Context GC 的装配在**两个平面**——web 现在**全部自动**,零配
|
|
|
527
540
|
|
|
528
541
|
#### 从 npm 安装后的第一印象(可感知 / 易引导 / 易配置)
|
|
529
542
|
|
|
530
|
-
-
|
|
531
|
-
|
|
543
|
+
- **半自动(opt-in)**:默认保留 DSH 自己的摘要;在设置卡打开 `gcReplacesCompaction`(host 平面)与
|
|
544
|
+
`autoWebCompaction`(web 预设)后,启动一次即由 `mountCompactionEngine` 接管、并把全部 stock
|
|
545
|
+
预设改写成 `dsh-engram/compaction`。开启后无需再手动改文件。
|
|
532
546
|
- **可感知**:插件启动时把权威状态写到 `$DSH_HOME/engram/context-gc.status.json`
|
|
533
547
|
(`host` 平面模式 + `web` 平面每个预设的接管结果 + 生效配置)。随时
|
|
534
548
|
`npx dsh-engram status` 或 `npx dsh-engram doctor` 查看;web 记忆看板(ESR 任务看板)头部也有
|
|
535
549
|
一枚状态徽标("Context GC·主机 ·N 预设",来自 overview API)。启动日志也有两行关键确认:
|
|
536
550
|
`engram context-gc: compaction = Context GC …` 与 `engram web-provision: wired Context GC into preset …`。
|
|
537
|
-
- **易配置**:一个设置卡(「记忆 GC」区)管全部:`autoWebCompaction`(web
|
|
538
|
-
`gcReplacesCompaction`(用 Context GC
|
|
551
|
+
- **易配置**:一个设置卡(「记忆 GC」区)管全部:`autoWebCompaction`(web 自动接管,默认关)、
|
|
552
|
+
`gcReplacesCompaction`(用 Context GC 还是宿主摘要,默认关)、`gcNarrative`(叙事兜底开关)——
|
|
539
553
|
改动后 `dsh web` 重启生效,web 预设行会被自动刷新成新配置。
|
|
540
554
|
|
|
541
555
|
**验证是否生效**:`dsh web`(或对应 profile)重启后——
|
|
@@ -548,7 +562,7 @@ Context GC 的装配在**两个平面**——web 现在**全部自动**,零配
|
|
|
548
562
|
- (若见 `… keeping the existing compaction service` 说明同域已有 provider、未替换成功;`web-provision … skipped (custom)`
|
|
549
563
|
说明某预设是自定义/无 compaction 布局、未被触碰;`dsh-compaction-basic unavailable` 说明环境缺依赖,自动回退默认压缩。)
|
|
550
564
|
|
|
551
|
-
### BoundaryPrune
|
|
565
|
+
### BoundaryPrune(子任务边界剪枝,默认开 + 账本否决)
|
|
552
566
|
|
|
553
567
|
Context GC 管「压缩的摘要内容」,BoundaryPrune 管「确定性剪枝的触发时机」——
|
|
554
568
|
在 todo 完成推进 / goal 终态这些子任务边界,主动调用 DSH 自带的
|
|
@@ -573,10 +587,13 @@ Context GC 管「压缩的摘要内容」,BoundaryPrune 管「确定性剪枝
|
|
|
573
587
|
并配更小保留边缘(`boundaryPruneHeadChars`/`boundaryPruneTailChars`)可更早
|
|
574
588
|
开剪——T2048+小边缘在真实语料上首剪节省是宿主默认的 2.4 倍(10.14M vs 4.23M
|
|
575
589
|
字符)。降阈值在 `resultPack` 开启时安全(被剪中段有归档兜底)。
|
|
576
|
-
-
|
|
577
|
-
|
|
590
|
+
- 默认**开**:`boundaryPrune: true`;`false` 是 opt-out。自适应闸门
|
|
591
|
+
(`boundaryPruneAdaptive: true`,默认开)让 Context Ledger 在该 workspace 真实剪枝后
|
|
592
|
+
净收益为负(≥3 次)时自动停剪——证据只能关、不会自行开。启动日志出现
|
|
593
|
+
`engram boundary-prune (todo @N reqs): pruned …`;被账本否决时出现
|
|
594
|
+
`engram boundary-prune: ledger gate holds for …`。
|
|
578
595
|
|
|
579
|
-
### ResultPack L2(结果归档 + `result_recall
|
|
596
|
+
### ResultPack L2(结果归档 + `result_recall`,默认开)
|
|
580
597
|
|
|
581
598
|
让 BoundaryPrune 剪枝**无损**:每个被剪工具结果的被移除中段,按与记忆写入
|
|
582
599
|
相同的规则脱敏后归档到 `~/.dsh/engram/resultpack/<callId>.json`,并在剪枝
|
|
@@ -591,8 +608,9 @@ Context GC 管「压缩的摘要内容」,BoundaryPrune 管「确定性剪枝
|
|
|
591
608
|
[ENGRAM] 索引);保留期 `resultPackRetentionDays`(默认 7 天)按 mtime 清理,
|
|
592
609
|
搭 GC 同一节奏。
|
|
593
610
|
- **自我禁用**:只开 L2 不开 L1 将无内容可归档,故不注册工具并打一条警告。
|
|
594
|
-
-
|
|
595
|
-
|
|
611
|
+
- 默认**开**:`resultPack: true`(与默认开启的 L1 配对,保证默认剪枝无损);
|
|
612
|
+
关掉后 L1 仍可工作,但被剪中段不可召回。开启时启动日志出现
|
|
613
|
+
`engram result-pack enabled: result_recall(callId, offset) registered`。
|
|
596
614
|
|
|
597
615
|
### 激活遥测(SoL-Pi M15/C13)
|
|
598
616
|
|
|
@@ -607,6 +625,45 @@ overview)现在返回 `activation: { boundaryPrune, recall }`:
|
|
|
607
625
|
(engram_recall 查询 → 命中 → engram_detail 下钻)闭合,可看到
|
|
608
626
|
注入→查询→下钻的完整激活。
|
|
609
627
|
|
|
628
|
+
### Context Ledger(净收益账本)
|
|
629
|
+
|
|
630
|
+
把「省 token」变成可核对的账。每个模型请求记一笔:注入的 `[ENGRAM]`/`[RECALL]`
|
|
631
|
+
与 `[ESR]` 块按存活请求数计入成本;被 BoundaryPrune 剪掉的结果按后续请求数计入
|
|
632
|
+
节省;每次剪枝按 `(1 − ledgerCacheDiscount)` 计一次前缀重写罚金(KV 缓存击穿)。
|
|
633
|
+
`GET /api/dsh-engram/stats` 与 `/overview` 返回 `ledger`:
|
|
634
|
+
|
|
635
|
+
- `totals` — `requests / injectedChars / avoidedChars / rewriteCount / rewriteChars /
|
|
636
|
+
netChars / netTokens`(`net = avoided − injected − rewriteChars × (1 − discount)`);
|
|
637
|
+
- `byWorkspace` / `byDay` — 按工作区、按天的同一口径,`byDay` 倒序;
|
|
638
|
+
- `openSessions` — 仍在累计、尚未落盘的会话数(进程重启最多丢 `flushEvery` 个请求的账)。
|
|
639
|
+
|
|
640
|
+
GUI「遥测」页签直接画这块账本(净 token 大数字 + 节省/注入/重写罚金三卡 + 近 14 天红绿柱),
|
|
641
|
+
记忆概览页也多一张「上下文净 token」卡。落盘在 `~/.dsh/engram/ledger.json`(原子写、按天滚动、
|
|
642
|
+
delta 落盘),进程内只做整数累加,热路径零 I/O、零模型调用。默认 `ledgerEnabled: true`、
|
|
643
|
+
`ledgerCacheDiscount: 0.1`;关掉 = 不挂监听、不写文件。**口径诚实**:token 按
|
|
644
|
+
`chars / 4` 估算,不含 provider 实际计费与模型质量差;Context GC 的压缩节省暂未
|
|
645
|
+
接入(宿主未暴露前后大小),因此账本只记「可证明」的部分。
|
|
646
|
+
|
|
647
|
+
### JIT 推送(v0.6-C)
|
|
648
|
+
|
|
649
|
+
拉取式召回被实证休眠(112 会话仅 24 次 `engram_recall`、8 次 `engram_detail`),所以
|
|
650
|
+
v0.6 增加按事件**推送**:三个确定性事件,命中才推、每次一行、每会话最多 3 行(`jitMaxLines`,
|
|
651
|
+
每行 `jitMaxLineChars`=220):
|
|
652
|
+
|
|
653
|
+
| 事件 | 触发条件 | 推什么 |
|
|
654
|
+
|---|---|---|
|
|
655
|
+
| 错误复发 | 同一 `cmd:` 签名第二次失败,且已有 error/procedure 记忆 | 该记忆的 id + 一行摘要 + `engram_detail` 下钻 |
|
|
656
|
+
| 文件焦点 | 同一文件连续第二次编辑,且有 filePath/dir 锚定记忆 | 优先 preference,其次 fact/decision |
|
|
657
|
+
| 目标完成 | goal complete/block 且有 active ESR 任务 | 前两个未闭环任务 + `esr_status` 提示 |
|
|
658
|
+
|
|
659
|
+
- **append-only**:推送行一旦出现就不再改写/撤回,前缀每次推送只变一次;
|
|
660
|
+
每次推送按 `estimatePrefixChars + 行长度` 记一次重写罚金(Context Ledger 的
|
|
661
|
+
`rewriteCount` / `rewriteChars`),净收益可在遥测页直接看。
|
|
662
|
+
- **无命中沉默**:没有可指向的记忆/任务就不推——宁可不推,也不灌噪声。
|
|
663
|
+
- **零 LLM、纯规则**;`jitEnabled:false` 一键关,`[JIT]` section 为空时不占任何 token。
|
|
664
|
+
- **尚未做**:resume brief(隔天继续)与「预计剩余请求不足时跳过推送」的显式 ROI 门——
|
|
665
|
+
当前靠 3 行硬预算 + 账本观测。
|
|
666
|
+
|
|
610
667
|
## 自动捕获策略
|
|
611
668
|
|
|
612
669
|
捕获是确定性、离线的——只看到工具*结果*,从不看对话本身。什么会被记录成一条记忆:
|
|
@@ -679,12 +736,13 @@ promote: 2 pending todo(s) vs 1 ESR task(s) — esr_task(name="…") #suggest-pr
|
|
|
679
736
|
autoCapture: true # 零 LLM 工具结果捕获
|
|
680
737
|
autoCapturePreferences: true # 零 LLM 用户纠正/偏好捕获(prefer/avoid/switch-to 句式)
|
|
681
738
|
preferenceCapturePerSession: 8 # 每会话偏好记忆条数上限
|
|
682
|
-
boundaryPrune:
|
|
739
|
+
boundaryPrune: true # ResultPack L1:todo/goal 边界剪掉超阈值旧工具结果(默认开)
|
|
740
|
+
boundaryPruneAdaptive: true # 账本否决:该 workspace 净收益为负(≥3 次剪枝)时自动停剪
|
|
683
741
|
boundaryPruneThresholdChars: 0 # 阈值覆盖(0=宿主 8192;如 2048 可更早开剪)
|
|
684
742
|
boundaryPruneHeadChars: 0 # 覆盖时的保留头部(0=宿主 4096)
|
|
685
743
|
boundaryPruneTailChars: 0 # 覆盖时的保留尾部(0=宿主 1024)
|
|
686
744
|
boundaryPruneIdleCadence: 0 # 空闲步数边界(0=仅事件边界;覆盖无 todo/goal 会话)
|
|
687
|
-
resultPack:
|
|
745
|
+
resultPack: true # ResultPack L2:剪掉的中段脱敏归档 + result_recall 按页召回(默认开,须与 L1 同开)
|
|
688
746
|
resultPackRetentionDays: 7 # 归档保留天数(mtime 清理,走 GC 节奏)
|
|
689
747
|
sessionSearch: true # engram_recall 也可对历史会话 FTS
|
|
690
748
|
recallScope: workspace # 召回范围:workspace(严格工作区隔离,默认)| global(可选跨工作区召回,带 [W:<ws>] 来源标记)
|
|
@@ -702,9 +760,12 @@ promote: 2 pending todo(s) vs 1 ESR task(s) — esr_task(name="…") #suggest-pr
|
|
|
702
760
|
gcEnabled: true # 定时记忆 GC
|
|
703
761
|
gcIntervalHours: 24 # 回收节奏
|
|
704
762
|
gcStableRetentionDays: 120 # 超过此天数的 stable 任务离开 [ESR]
|
|
705
|
-
gcReplacesCompaction:
|
|
763
|
+
gcReplacesCompaction: false # Context GC:接管 DSH 自动 compact(默认关=宿主 LLM 压缩;true=opt-in 指针摘要)
|
|
706
764
|
gcNarrative: true # 无锚轮次走 scoped LLM 叙事;false=纯机械(零 LLM)
|
|
707
|
-
|
|
765
|
+
jitEnabled: true # JIT 推送:错误复发/文件焦点/goal 完成时推一行已有记忆
|
|
766
|
+
ledgerEnabled: true # Context Ledger:注入成本/剪枝节省/前缀重写罚金 → 净 token
|
|
767
|
+
ledgerCacheDiscount: 0.1 # 缓存折价:重写按 (1−0.1) 计罚金;0.1 = 命中只付 10%
|
|
768
|
+
autoWebCompaction: false # web 预设自动改写(默认关;开启需显式确认,可用 revert 还原)
|
|
708
769
|
boundaryPruneMinRemaining: 50 # 偿还门:预计剩余请求数低于此值不剪
|
|
709
770
|
engramIndexOrder: 40 # systemPrompt section 顺序(位于 tools 段之前)
|
|
710
771
|
esrOrder: 41
|
|
@@ -713,7 +774,7 @@ promote: 2 pending todo(s) vs 1 ESR task(s) — esr_task(name="…") #suggest-pr
|
|
|
713
774
|
## 开发
|
|
714
775
|
|
|
715
776
|
```sh
|
|
716
|
-
npm test #
|
|
777
|
+
npm test # 359 个测试:核心 + Web API + GC + Context GC + ESR 触发 + Context Ledger + JIT(node:test)
|
|
717
778
|
npm run build:client
|
|
718
779
|
```
|
|
719
780
|
|