@a9i5k4/dsh-auto-memory 3.1.5 → 3.1.7

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.
Files changed (93) hide show
  1. package/docs/CONTINUITY-FLOW.md +6 -6
  2. package/docs/HANDBOOK.md +54 -53
  3. package/docs/M-CM-PLAN.md +1 -1
  4. package/docs/M-CM-STATE.md +1 -1
  5. package/docs/M-CM7-HANDOFF-LAYERED-RETRIEVAL.md +1 -1
  6. package/docs/M3B-CONTRACT.md +7 -7
  7. package/docs/M7-AUTONOMOUS-STATE.md +1 -1
  8. package/docs/M7-TASKSET-DISPATCH.md +1 -1
  9. package/docs/PROMPT-PACK-LAYERED-RECALL.md +3 -3
  10. package/docs/PROMPT-SET-STRICT.md +3 -3
  11. package/docs/RELEASE-GO-NOGO.md +1 -1
  12. package/docs/STATUS-BOARD.md +1 -1
  13. package/docs/USER-GUIDE.en.md +21 -21
  14. package/docs/USER-GUIDE.zh-CN.md +21 -21
  15. package/docs/WHITEPAPER.md +1 -1
  16. package/docs/prompts/FIX-AGENT-P12-FULL-REGRESSION.md +1 -1
  17. package/docs/prompts/LIVE-VERIFY-ZCODE.md +2 -2
  18. package/docs/prompts/P2-semantic-recall.md +2 -2
  19. package/docs/prompts/P7-write-fix.md +1 -1
  20. package/docs/prompts/RELEASE-AGENT.md +4 -4
  21. package/docs/prompts/ZCODE-DROPIN.md +1 -1
  22. package/lib/acceptance.js +6 -6
  23. package/lib/activation-host.js +15 -14
  24. package/lib/activation-inbox-state.js +4 -4
  25. package/lib/activation-inbox.js +44 -44
  26. package/lib/board-mode.js +3 -3
  27. package/lib/client.js +225 -41
  28. package/lib/config-io.js +12 -12
  29. package/lib/context-bridge.js +22 -22
  30. package/lib/context-host.js +24 -23
  31. package/lib/datadir.js +95 -0
  32. package/lib/degrade.js +21 -21
  33. package/lib/dsh-home.js +8 -8
  34. package/lib/engine-identity.js +12 -12
  35. package/lib/engine-switch.js +3 -3
  36. package/lib/episodic-store.js +13 -13
  37. package/lib/evidence-agg.js +4 -4
  38. package/lib/evidence-store.js +12 -12
  39. package/lib/fact-store.js +47 -47
  40. package/lib/handoff-anchor.js +4 -4
  41. package/lib/hub-io.js +356 -3
  42. package/lib/index-sync.js +5 -5
  43. package/lib/index.js +426 -242
  44. package/lib/intent-clean-safe.js +3 -3
  45. package/lib/intent-clean.js +1 -1
  46. package/lib/l0-extract.js +15 -15
  47. package/lib/l0-index-sync.js +8 -8
  48. package/lib/l0-index.js +11 -11
  49. package/lib/ledger-criteria.js +8 -8
  50. package/lib/m4-corpus.js +1 -1
  51. package/lib/m7-index-sync-host.js +2 -2
  52. package/lib/m7-wire.js +24 -24
  53. package/lib/memory-anchor.js +1 -1
  54. package/lib/memory-envelope.js +15 -15
  55. package/lib/memory-hub.js +95 -50
  56. package/lib/memory-importance.js +7 -7
  57. package/lib/memory-mutation.js +5 -5
  58. package/lib/note-status-apply.js +2 -2
  59. package/lib/note-status.js +7 -7
  60. package/lib/policies/activation_policy_v2.json +2 -2
  61. package/lib/policies/recall_intent_lr_v1.json +1 -1
  62. package/lib/procedure-observation.js +2 -2
  63. package/lib/procedure-store.js +117 -28
  64. package/lib/python-setup.js +6 -5
  65. package/lib/python-sidecar-client.js +26 -26
  66. package/lib/recall-fusion.js +12 -12
  67. package/lib/recall-stats.js +36 -1
  68. package/lib/rerank-host.js +11 -11
  69. package/lib/rules-edit.js +9 -9
  70. package/lib/rules-layer.js +26 -26
  71. package/lib/semantic-decide.js +7 -7
  72. package/lib/semantic-js.js +13 -13
  73. package/lib/shadow-host.js +7 -6
  74. package/lib/shadow-retrieval.js +40 -40
  75. package/lib/skill-export-host.js +7 -7
  76. package/lib/skill-export.js +6 -6
  77. package/lib/state-commit.js +10 -10
  78. package/lib/storage-manage.js +6 -6
  79. package/lib/tier-layer-inject.js +28 -28
  80. package/lib/tier0-catalog.js +4 -4
  81. package/lib/wb-contract.js +45 -45
  82. package/lib/wb-sidecar.js +11 -11
  83. package/package.json +3 -4
  84. package/python/m7_activation_features_v2.py +7 -7
  85. package/python/m7_embedding_v1.py +12 -12
  86. package/python/policies/activation_policy_v2.json +2 -2
  87. package/python/policies/decision-record-activation-v2-delta-exp-override-20260824.json +1 -1
  88. package/python/policies/decision-record-reasoning-kind-admission-20260826.json +2 -2
  89. package/python/policies/decision-record-stale-gate-per-candidate-20260825.json +2 -2
  90. package/python/policies/recall_intent_lr_v1.json +1 -1
  91. package/python/verify_policy_artifact.py +3 -3
  92. package/python/worker_semantic_v1.py +18 -18
  93. package/python/worker_v1.py +18 -18
@@ -6,7 +6,7 @@ Extends the tested M7-0/M7-1 fake worker (python/worker_v1.py) WITHOUT
6
6
  touching its protocol semantics: same JSONL framing, same validators, same
7
7
  index_sync rejection matrix, same atomic derived-corpus persistence. Adds:
8
8
 
9
- - after a successful index_sync commit: chunk (m7_chunk_v1) + embed
9
+ - after a successful index_sync commit: chunk (m7_chunk_pre_v1) + embed
10
10
  (frozen provider) every record and persist versioned vectors with an
11
11
  identity block under <dsh-home>/memory/semantic/ (atomic replace)
12
12
  - on startup: reuse persisted vectors only when the identity block
@@ -19,7 +19,7 @@ index_sync rejection matrix, same atomic derived-corpus persistence. Adds:
19
19
 
20
20
  Embedding backend is selected by an optional JSON config file passed via
21
21
  the DSH_M7_EMBEDDING_CONFIG environment variable (no CLI change, no JS
22
- change): {"provider":"bge-m3-v1"|"hash-v1", "modelDir":...,
22
+ change): {"provider":"bge-m3-pre-v1"|"hash-pre-v1", "modelDir":...,
23
23
  "modelRevision":..., "dimension":1024, "torchThreads":16}.
24
24
  Without the env var the worker degrades to fake-worker behavior (protocol
25
25
  alive, embedding not ready) - never crashes, never changes ack semantics.
@@ -51,24 +51,24 @@ SHADOW_TOP_K = 8
51
51
 
52
52
 
53
53
  def canonical_workspace_key(key):
54
- """Byte-twin of lib/evidence-store.js canonicalWorkspaceKey:
54
+ """Byte-twin of lib/evidence-store-pre.js canonicalWorkspaceKey:
55
55
  path.resolve + backslash->slash + lowercase."""
56
56
  return os.path.abspath(str(key == None and '' or key)).replace('\\', '/').lower()
57
57
 
58
58
 
59
59
  def wsref_of(workspace_key):
60
- """Byte-twin of evidence-store.js workspaceRefOf. JS owns identity;
60
+ """Byte-twin of evidence-store-pre.js workspaceRefOf. JS owns identity;
61
61
  this is a deterministic reproduction of its published pure function so
62
62
  the worker can apply the workspace/scope/miv triple filter required by
63
63
  the M7-7.5 hardening audit (P1: isolation must be explicit, never an
64
64
  artifact of differing miv values)."""
65
65
  canon = canonical_workspace_key(workspace_key)
66
66
  return 'wsr_' + hashlib.sha256(
67
- ('evidence-wsref-v1\u0000' + canon).encode('utf-8')).hexdigest()[:32]
67
+ ('evidence-wsref-pre-v1\u0000' + canon).encode('utf-8')).hexdigest()[:32]
68
68
 
69
69
 
70
70
  def _tokenize(text, stopwords=frozenset()):
71
- """lexical_v2 parity tokenizer: NFKC + CJK 2-gram + ascii tokens."""
71
+ """lexical_pre_v2 parity tokenizer: NFKC + CJK 2-gram + ascii tokens."""
72
72
  t = unicodedata.normalize('NFKC', str(text)).lower()
73
73
  out = []
74
74
  for run in __import__('re').findall(r'[\u4e00-\u9fff]+|[a-z0-9_./-]+', t):
@@ -111,7 +111,7 @@ class LexicalBM25:
111
111
  return s
112
112
 
113
113
  # ---- M7-6 activation policy (default: shadow calibration only) ----
114
- ACTIVATION_POLICY_VERSION = 'm7_semantic_threshold_v1'
114
+ ACTIVATION_POLICY_VERSION = 'm7_semantic_threshold_pre_v1'
115
115
  DEFAULT_ACTIVATION_POLICY = {
116
116
  'mode': 'shadow', # 'shadow' = calibrate/log only; 'active' = emit frames
117
117
  'tOn': 0.62, 'tOff': 0.52, # dual threshold, T_on > T_off (hysteresis)
@@ -166,7 +166,7 @@ class SemanticWorker(base.Worker):
166
166
  # 'shadow'(默认)=只记 shadow 行零发射;'canary-explicit'=仅 explicit 车道
167
167
  # 的 emit 决策发 activation_request 帧;'active' 预留。非法值回退 shadow
168
168
  # (fail closed)。此开关属 JS/用户运营面,不进策略工件——阈值权威仍在
169
- # activation_policy_v2.json(append-only),发射节流依赖 M6 收件箱的
169
+ # activation_policy_pre_v2.json(append-only),发射节流依赖 M6 收件箱的
170
170
  # 硬校验+cooldown+TTL+latest-wins,worker 侧不重复限速。
171
171
  _em = str(self.embedding_config.get('activationEmitMode') or 'shadow')
172
172
  self.activation_emit_mode = _em if _em in (
@@ -184,9 +184,9 @@ class SemanticWorker(base.Worker):
184
184
  'policies')
185
185
  try:
186
186
  self._fv2 = featv2.load_and_verify_policy(
187
- os.path.join(pol_dir, 'recall_intent_lr_v1.json'),
187
+ os.path.join(pol_dir, 'recall_intent_lr_pre_v1.json'),
188
188
  os.path.join(pol_dir,
189
- 'activation_policy_v2.json'))
189
+ 'activation_policy_pre_v2.json'))
190
190
  except Exception as exc: # fail closed, retrieval unaffected
191
191
  self._fv2_invalid = str(exc)[:200]
192
192
  base.diag('featuresV2-policy-invalid: ' + self._fv2_invalid)
@@ -361,7 +361,7 @@ class SemanticWorker(base.Worker):
361
361
  payload = {
362
362
  'schemaVersion': 1,
363
363
  'namespace': base.NAMESPACE,
364
- 'policyVersion': 'semantic_vectors_v1',
364
+ 'policyVersion': 'semantic_vectors_pre_v1',
365
365
  'identity': identity,
366
366
  'workspaceRef': ws_ref,
367
367
  'scope': scope,
@@ -627,7 +627,7 @@ class SemanticWorker(base.Worker):
627
627
  if len(excerpt.encode('utf-8')) > 480:
628
628
  excerpt = excerpt[:150]
629
629
  cands.append({
630
- 'candidateId': 'cand_' + base.first32(
630
+ 'candidateId': 'cand_pre_' + base.first32(
631
631
  base.sha_str('m7-semantic-cand\u0000' + obs + '\u0000' +
632
632
  c['memoryId'] + '\u0000' + str(i))),
633
633
  'memoryId': c['memoryId'], 'anchorId': c['anchorId'],
@@ -639,8 +639,8 @@ class SemanticWorker(base.Worker):
639
639
  })
640
640
  if not cands:
641
641
  return None
642
- activation_id = 'act_' + base.first32(
643
- base.sha_str('m7-semantic-activation-v1\u0000' + obs))
642
+ activation_id = 'act_pre_' + base.first32(
643
+ base.sha_str('m7-semantic-activation-pre-v1\u0000' + obs))
644
644
  created = req.get('sentAt', 0)
645
645
  ttl = int(pol['ttlSteps'])
646
646
  return {
@@ -736,7 +736,7 @@ class SemanticWorker(base.Worker):
736
736
 
737
737
  # ---------- M7-7 judgement shadow (audit only, never writes) ----------
738
738
 
739
- JUDGEMENT_POLICY = 'judgement_shadow_v1'
739
+ JUDGEMENT_POLICY = 'judgement_shadow_pre_v1'
740
740
 
741
741
  _J_MARKERS = ('CORRECTION', 'UPDATED', 'REVISED', 'FREEZE',
742
742
  'HARD RULE', 'DECISION reversing', '纠正', '更新:',
@@ -911,7 +911,7 @@ class SemanticWorker(base.Worker):
911
911
  self._append_shadow({
912
912
  'schemaVersion': 1,
913
913
  'namespace': base.NAMESPACE,
914
- 'policyVersion': 'semantic_shadow_v1',
914
+ 'policyVersion': 'semantic_shadow_pre_v1',
915
915
  'observationId': str(p.get('observationId', '')),
916
916
  'workerEpoch': str(req.get('workerEpoch', '')),
917
917
  'memoryIndexVersion': miv,
@@ -1063,7 +1063,7 @@ class SemanticWorker(base.Worker):
1063
1063
 
1064
1064
  def _intent_config_hash(self):
1065
1065
  ip_path = os.path.join(os.path.dirname(os.path.abspath(__file__)),
1066
- 'policies', 'recall_intent_lr_v1.json')
1066
+ 'policies', 'recall_intent_lr_pre_v1.json')
1067
1067
  try:
1068
1068
  with open(ip_path, encoding='utf-8') as f:
1069
1069
  ip = json.load(f)
@@ -1367,7 +1367,7 @@ def main():
1367
1367
  args, _unknown = ap.parse_known_args()
1368
1368
  if args.selftest:
1369
1369
  base.run_selftest()
1370
- w = SemanticWorker('ep', '', {'provider': 'hash-v1',
1370
+ w = SemanticWorker('ep', '', {'provider': 'hash-pre-v1',
1371
1371
  'dimension': 64})
1372
1372
  view = w.embedding_view()
1373
1373
  assert view['enabled'] is True and view['ready'] is False
@@ -24,9 +24,9 @@ import sys
24
24
  import tempfile
25
25
  import time
26
26
 
27
- PROTOCOL = 'm7_wire_v1'
28
- NAMESPACE = 'dsh-auto-memory'
29
- INDEX_POLICY = 'index_sync_v1'
27
+ PROTOCOL = 'm7_wire_pre_v1'
28
+ NAMESPACE = 'dsh-auto-memory-pre'
29
+ INDEX_POLICY = 'index_sync_pre_v1'
30
30
  MAX_LINE_BYTES = 256 * 1024
31
31
  MAX_RECORDS_PER_PAGE = 64
32
32
  # ★2026-09-17 修「索引永久不就绪 → 语义唤回全程降级」:JS 侧契约是「新 miv latest-wins;
@@ -47,9 +47,9 @@ PY_TYPES = frozenset(['health_result', 'context_ack', 'index_ack', 'activation_r
47
47
 
48
48
  RE_MEMORY_ID = re.compile(r'^mem_[0-9a-f]{32}$')
49
49
  RE_HEX64 = re.compile(r'^[0-9a-f]{64}$')
50
- RE_IDX = re.compile(r'^idx_[0-9a-f]{32}$')
50
+ RE_IDX = re.compile(r'^idx_pre_[0-9a-f]{32}$')
51
51
  RE_WSR = re.compile(r'^wsr_[0-9a-f]{32}$')
52
- RE_OBS = re.compile(r'^obs_')
52
+ RE_OBS = re.compile(r'^obs_pre_')
53
53
  RE_SOURCE_REF = re.compile(r'^(user|workspace|workspace-log):[A-Za-z0-9._\u4e00-\u9fff-]+$')
54
54
 
55
55
  _stderr_used = {'n': 0}
@@ -84,7 +84,7 @@ def dumps(v):
84
84
 
85
85
 
86
86
  def canonical(v):
87
- """Byte-identical twin of lib/m7-wire.js canonicalJson()."""
87
+ """Byte-identical twin of lib/m7-wire-pre.js canonicalJson()."""
88
88
  if v is None:
89
89
  return 'null'
90
90
  if isinstance(v, bool):
@@ -105,7 +105,7 @@ class ProtocolError(Exception):
105
105
  self.detail = detail
106
106
 
107
107
 
108
- # ---------- payload validators (mirror of lib/m7-wire.js) ----------
108
+ # ---------- payload validators (mirror of lib/m7-wire-pre.js) ----------
109
109
 
110
110
 
111
111
  def validate_semantic_record(rec):
@@ -126,7 +126,7 @@ def validate_semantic_record(rec):
126
126
  need(RE_HEX64.match(str(rec.get('recordDigest', ''))), 'recordDigest')
127
127
  need(rec.get('heading') is None or isinstance(rec.get('heading'), str), 'heading')
128
128
  need(isinstance(rec.get('text'), str), 'text')
129
- need(isinstance(rec.get('chunkId'), str) and str(rec.get('chunkId')).startswith('chk_'), 'chunkId')
129
+ need(isinstance(rec.get('chunkId'), str) and str(rec.get('chunkId')).startswith('chk_pre_'), 'chunkId')
130
130
  ordinal = rec.get('chunkOrdinal')
131
131
  count = rec.get('chunkCount')
132
132
  need(isinstance(ordinal, int) and not isinstance(ordinal, bool) and ordinal >= 0, 'chunkOrdinal')
@@ -219,7 +219,7 @@ class Worker:
219
219
 
220
220
  def maybe_activation(self, req, p):
221
221
  """Deterministic fake ActivationRequestPre copied from JS-owned provenance.
222
- Emits only when the frame carries valid identity + idx_ index version;
222
+ Emits only when the frame carries valid identity + idx_pre_ index version;
223
223
  otherwise stays silent (fail closed). Field-compatible with M6 validator."""
224
224
  miv = str((p.get('index') or {}).get('memoryIndexVersion', ''))
225
225
  if not RE_IDX.match(miv):
@@ -257,9 +257,9 @@ class Worker:
257
257
  continue
258
258
  if not RE_HEX64.match(fdig) or not RE_HEX64.match(rdig):
259
259
  continue
260
- activation_id = 'act_' + first32(sha_str('m7-fake-activation-v1\u0000' + obs))
260
+ activation_id = 'act_pre_' + first32(sha_str('m7-fake-activation-pre-v1\u0000' + obs))
261
261
  cand = {
262
- 'candidateId': 'cand_' + first32(sha_str(activation_id + '\u0000' + mid + '\u0000' + str(i))),
262
+ 'candidateId': 'cand_pre_' + first32(sha_str(activation_id + '\u0000' + mid + '\u0000' + str(i))),
263
263
  'memoryId': mid,
264
264
  'anchorId': aid,
265
265
  'scope': rscope,
@@ -273,7 +273,7 @@ class Worker:
273
273
  candidates.append(cand)
274
274
  if not candidates:
275
275
  return None
276
- activation_id = 'act_' + first32(sha_str('m7-fake-activation-v1\u0000' + obs))
276
+ activation_id = 'act_pre_' + first32(sha_str('m7-fake-activation-pre-v1\u0000' + obs))
277
277
  created = req.get('sentAt', 0)
278
278
  ttl_steps = 2
279
279
  activation = {
@@ -290,7 +290,7 @@ class Worker:
290
290
  'contextVersion': cv,
291
291
  'memoryIndexVersion': miv,
292
292
  'threshold': {
293
- 'policyVersion': 'm7_fake_threshold_v1',
293
+ 'policyVersion': 'm7_fake_threshold_pre_v1',
294
294
  'score': 0.92,
295
295
  'threshold': 0.8,
296
296
  'reason': 'deterministic fake activation (python worker)',
@@ -326,7 +326,7 @@ class Worker:
326
326
  require(isinstance(p, dict), 'invalid-payload', 'not-object')
327
327
  require(p.get('schemaVersion') == 1, 'invalid-payload', 'schemaVersion')
328
328
  sync_id = str(p.get('syncId', ''))
329
- require(sync_id.startswith('syn_'), 'invalid-payload', 'syncId')
329
+ require(sync_id.startswith('syn_pre_'), 'invalid-payload', 'syncId')
330
330
  ws_ref = str(p.get('workspaceRef', ''))
331
331
  require(RE_WSR.match(ws_ref), 'invalid-payload', 'workspaceRef')
332
332
  scope = p.get('scope')
@@ -469,7 +469,7 @@ class Worker:
469
469
  for i in range(st['pageCount']):
470
470
  flat.extend(st['pages'][i])
471
471
  expected_final = sha_hex(canonical({
472
- 'kind': 'index_sync_final_v1',
472
+ 'kind': 'index_sync_final_pre_v1',
473
473
  'syncId': st['syncId'],
474
474
  'memoryIndexVersion': st['memoryIndexVersion'],
475
475
  'workspaceRef': st['workspaceRef'],
@@ -511,7 +511,7 @@ class Worker:
511
511
  'records': e['records'],
512
512
  })
513
513
  payload = {'schemaVersion': 1, 'namespace': NAMESPACE,
514
- 'policyVersion': 'semantic_derived_v1', 'entries': entries}
514
+ 'policyVersion': 'semantic_derived_pre_v1', 'entries': entries}
515
515
  data = (dumps(payload) + '\n').encode('utf-8')
516
516
  try:
517
517
  os.makedirs(dir_path, exist_ok=True)
@@ -584,10 +584,10 @@ def run_selftest():
584
584
  assert frames[0]['frameId'] == 'res_' + first32(sha_str('r1:health_result'))
585
585
  checks += 1
586
586
  push = {'requestId': 'r2', 'workerEpoch': 'ep', 'sentAt': 20, 'frameId': 'f2', 'type': 'context_push',
587
- 'payload': {'kind': 'context_push', 'observationId': 'obs_' + '0' * 32,
587
+ 'payload': {'kind': 'context_push', 'observationId': 'obs_pre_' + '0' * 32,
588
588
  'session': {'sessionId': 's', 'agentId': 'a', 'workspaceKey': 'w', 'scope': 'Workspace'},
589
589
  'cursor': {'eventSeq': 1, 'contextVersion': 3},
590
- 'index': {'memoryIndexVersion': 'idx_' + 'ab' * 16}, 'memoryRefs': []}}
590
+ 'index': {'memoryIndexVersion': 'idx_pre_' + 'ab' * 16}, 'memoryRefs': []}}
591
591
  f2 = w.handle_frame(push)
592
592
  assert len(f2) == 1 and f2[0]['payload']['accepted'] is True
593
593
  again = w.handle_frame(push)