@furongjun1999/dsh-memory 0.5.0 → 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 +572 -465
- package/docs/README.md +1 -0
- package/docs/eval/DSH/346/227/245/345/277/227/347/264/242/345/274/225v2_/345/217/202/350/200/203dsh-TUI_v1.0.md +248 -0
- package/docs/eval/DSH/346/227/245/345/277/227/347/264/242/345/274/225/346/225/210/346/236/234/351/252/214/350/257/201_v1.0.md +209 -0
- package/docs/eval/DSH/347/253/257/347/274/272/351/231/267/344/270/223/351/241/271_v1.0.md +254 -0
- package/docs/eval/P1b2_/350/257/273/351/235/242/344/273/243/351/231/205/344/277/256/345/244/215_v1.0.md +124 -0
- package/docs/eval/bench_lingshu_self/bench_self.py +140 -0
- package/docs/eval/bench_lingshu_self/self_bench_result.json +404 -0
- package/docs/eval/bench_lingshu_self//347/201/265/346/236/242/350/207/252/345/272/223/347/253/257/345/210/260/347/253/257/346/243/200/347/264/242/345/256/236/346/265/213_v1.0.md +38 -0
- package/docs/eval//344/270/215/345/217/257/351/235/240/346/200/247/350/220/275/345/234/260_P0_v1.0.md +185 -0
- package/docs/eval//345/217/221/345/270/20306_/344/270/200/351/224/256/351/205/215/347/275/256/344/270/216DSH0172_v1.0.md +171 -0
- package/docs/eval//346/225/205/351/232/234/346/263/250/345/205/245/345/256/236/346/265/213_v1.0.md +422 -0
- package/docs/eval//347/253/257/345/210/260/347/253/257LoCoMoQA/345/220/214/345/217/243/345/276/204/345/257/271/347/205/247_v1.0.md +100 -0
- package/docs/eval//347/253/257/345/210/260/347/253/257/345/271/262/346/211/260/346/261/240/350/257/204/346/265/213_/347/241/256/345/256/232/346/200/247/350/243/201/345/206/263vsLLM_judge_v1.1.md +197 -0
- package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v1.md +156 -0
- package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v10.md +210 -0
- package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v11.md +227 -0
- package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v12.md +203 -0
- package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v13.md +233 -0
- package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v14.md +191 -0
- package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v15.md +213 -0
- package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v16.md +214 -0
- package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v17.md +199 -0
- package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v18.md +183 -0
- package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v19.md +207 -0
- package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v2.md +156 -0
- package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v3.md +152 -0
- package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v4.md +128 -0
- package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v5.md +114 -0
- package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v6.md +192 -0
- package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v7.md +187 -0
- package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v8.md +207 -0
- package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v9.md +203 -0
- package/docs/hive//345/256/211/345/205/250/345/256/241/350/256/241/345/256/236/351/224/232_v0.1.md +202 -0
- package/docs/hive//350/234/202/345/267/242/345/217/214/345/256/236/344/276/213/344/272/222/351/252/214_/350/256/276/350/256/241/345/256/232/347/250/277.md +19 -3
- package/docs/images/lingshu-moonlight-covenant-poster-preview.jpg +0 -0
- package/docs/images/lingshu-moonlight-covenant-poster.png +0 -0
- package/docs/mdcg//345/212/237/350/203/275/350/260/203/347/224/250/346/230/240/345/260/204/350/241/250_v0.1.md +40 -40
- package/docs/theory//344/270/215/345/217/257/351/235/240/345/256/232/347/220/206/344/270/216/345/244/261/346/225/210/344/274/230/345/205/210/346/241/206/346/236/266_v0.3.md +365 -0
- package/docs//344/270/215/345/217/257/351/235/240/346/200/247/347/220/206/350/256/272_v0.1.md +343 -0
- package/dsh/cordis-patch-profile-web.example.yml +35 -0
- package/lib/bridge.d.ts +9 -0
- package/lib/bridge.js +35 -0
- package/lib/cli.d.ts +3 -0
- package/lib/cli.js +66 -0
- package/lib/index.js +7 -1
- package/lib/init.d.ts +88 -0
- package/lib/init.js +287 -0
- package/lib/lib/roleplay_web.js +530 -443
- package/lib/lib/token_store.d.ts +7 -1
- package/lib/lib/token_store.js +12 -3
- package/md_cg/audit.py +12 -1
- package/md_cg/backfill.py +16 -15
- package/md_cg/backfill_bucket_zh.py +35 -0
- package/md_cg/bench_e2e_judge.py +532 -0
- package/md_cg/bench_e2e_locomo_qa.py +368 -0
- package/md_cg/bench_e2e_qa.py +256 -0
- package/md_cg/branches.py +18 -2
- package/md_cg/ccgc.py +3 -2
- package/md_cg/chain.py +19 -4
- package/md_cg/consolidate.py +7 -6
- package/md_cg/crosscheck.py +4 -3
- package/md_cg/crypto.py +439 -437
- package/md_cg/datapath.py +395 -335
- package/md_cg/evidence.py +8 -3
- package/md_cg/export.py +3 -1
- package/md_cg/forgetting.py +2 -2
- package/md_cg/fsutil.py +48 -0
- package/md_cg/hotcache.py +255 -238
- package/md_cg/interop.py +161 -22
- package/md_cg/judgment_manifest.py +177 -0
- package/md_cg/links.py +655 -622
- package/md_cg/mcp_server.py +282 -31
- package/md_cg/mdcg.py +702 -126
- package/md_cg/mdcos.py +454 -68
- package/md_cg/mreview/govern.py +5 -4
- package/md_cg/postings.py +4 -2
- package/md_cg/readcache.py +76 -18
- package/md_cg/reconcile.py +228 -0
- package/md_cg/review_cli.py +215 -0
- package/md_cg/routing.py +28 -0
- package/md_cg/run_tests.py +211 -0
- package/md_cg/scrub.py +862 -852
- package/md_cg/security.py +385 -275
- package/md_cg/selfreport.py +3 -2
- package/md_cg/signer.py +565 -562
- package/md_cg/sources.py +3 -2
- package/md_cg/stg.py +6 -0
- package/md_cg/sustain.py +1168 -1138
- package/md_cg/test_access_hints.py +147 -0
- package/md_cg/test_branch_discard_tombstone.py +136 -0
- package/md_cg/test_branches.py +259 -249
- package/md_cg/test_chain_read_isolate.py +168 -0
- package/md_cg/test_datapath_device_name.py +203 -0
- package/md_cg/test_emit_negtail_cache.py +156 -0
- package/md_cg/test_en_pipeline.py +186 -166
- package/md_cg/test_govern_directread.py +421 -0
- package/md_cg/test_i32_hotcache_env_key.py +218 -0
- package/md_cg/test_identity_attribution.py +228 -147
- package/md_cg/test_index_crossprocess_reload.py +301 -0
- package/md_cg/test_index_durability.py +238 -224
- package/md_cg/test_interop.py +4 -2
- package/md_cg/test_interop_judgment.py +228 -0
- package/md_cg/test_issue39_utf8_stdio.py +273 -0
- package/md_cg/test_links_concurrent_write.py +188 -0
- package/md_cg/test_merge_upsert.py +168 -0
- package/md_cg/test_n123_derive_expiry_chain.py +205 -0
- package/md_cg/test_n130_verify_falsified_protect.py +185 -0
- package/md_cg/test_n131_merge_gate.py +205 -0
- package/md_cg/test_none_id_write_guard.py +165 -0
- package/md_cg/test_p1x_ref_root.py +160 -0
- package/md_cg/test_p27_docindex.py +774 -765
- package/md_cg/test_p2_mcp.py +3 -0
- package/md_cg/test_p32_backfill.py +304 -298
- package/md_cg/test_p39_verify_flow.py +90 -50
- package/md_cg/test_p47_session_view.py +60 -25
- package/md_cg/test_propose_tail_index.py +157 -0
- package/md_cg/test_read_scope_b27.py +277 -0
- package/md_cg/test_readcache_default_on.py +168 -0
- package/md_cg/test_readcache_precise_inval.py +270 -0
- package/md_cg/test_readcache_prodpath.py +55 -7
- package/md_cg/test_reconcile_v0.py +294 -0
- package/md_cg/test_retr_s1.py +6 -2
- package/md_cg/test_retr_s1b.py +67 -0
- package/md_cg/test_retr_s7.py +8 -0
- package/md_cg/test_retr_s9_entity_ctx.py +181 -175
- package/md_cg/test_retr_score_once.py +208 -0
- package/md_cg/test_review_cli_attribution.py +177 -0
- package/md_cg/test_review_cli_visibility.py +235 -0
- package/md_cg/test_review_onepass.py +170 -0
- package/md_cg/test_rrf_graph_seed_cache.py +154 -0
- package/md_cg/test_security_audit.py +155 -0
- package/md_cg/test_security_audit_b26.py +161 -0
- package/md_cg/test_security_audit_v21.py +250 -0
- package/md_cg/test_semantic_canonical.py +255 -241
- package/md_cg/test_session_isolation.py +168 -0
- package/md_cg/test_snapshot_autoclose.py +187 -0
- package/md_cg/test_tail_watermark_race.py +208 -0
- package/md_cg/test_tenant_env_override_warn.py +139 -0
- package/md_cg/test_tenant_registry_corrupt_warn.py +151 -0
- package/md_cg/test_v14_fixes.py +415 -397
- package/md_cg/test_verify_dirty_reconcile.py +157 -0
- package/md_cg/theory.py +276 -273
- package/md_cg/tokens.py +734 -677
- package/md_cg/units.py +3 -2
- package/md_cg/vision_evidence.py +4 -3
- package/md_cg/whitebox_kb/wisdom/code_solidified.json +6195 -6195
- package/md_cg/whitebox_kb/wisdom/multilang_ir.py +128 -124
- package/md_cg/writepipe.py +554 -550
- package/package.json +11 -2
- package/src/bridge.ts +434 -401
- package/src/cli.ts +65 -0
- package/src/index.ts +526 -518
- package/src/init.ts +347 -0
- package/src/lib/roleplay_web.ts +1019 -932
- package/src/lib/token_store.ts +202 -192
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""test_p1x_ref_root.py · P1-X 回归守卫:op=ref / index_code / index_doc 的根白名单
|
|
3
|
+
|
|
4
|
+
安全缺陷(两份独立报告合并,severity=high):op=ref 是越权任意文件读原语——
|
|
5
|
+
probe_ref 以调用方自报的 root 与 ref.path 直接 os.path.join 后 open 全文回读
|
|
6
|
+
(refindex.py),无租户根校验、无 check_path_root、无密级闸。三形态全部漏:
|
|
7
|
+
|
|
8
|
+
① 自报 root 指向记忆根外(victim/secret.txt 全文进模型上下文);
|
|
9
|
+
② ref.path 绝对路径(os.path.join 遇绝对路径丢弃 root);
|
|
10
|
+
③ '../' 上跳。
|
|
11
|
+
同族缺口:index_code / index_doc 的 path 同样不走 check_path_root
|
|
12
|
+
(P1-4 只覆盖 ingest/export/link/mdcg_ingest)。
|
|
13
|
+
|
|
14
|
+
修复:_ref_call 的 read/get 分支按「最终将打开的完整路径」挂
|
|
15
|
+
check_path_root(MDCG_INGEST_ROOT);index_code/index_doc 对模型可控的显式
|
|
16
|
+
path 挂同闸。语义与 P1-4 先例一致:env 未设置 = 放开(部署开关,默认行为
|
|
17
|
+
不变);设置了 = realpath 落根内否则拒(fail-closed,上跳与绝对路径在
|
|
18
|
+
realpath 归一后自然涵盖)。
|
|
19
|
+
|
|
20
|
+
本文件钉死:三形态 + 索引越界必须拒绝;白名单内索引/回读不误伤;
|
|
21
|
+
env 未设保持放开语义;ingest 先例闸与 guest op 闸不回归。
|
|
22
|
+
运行:python -m md_cg.test_p1x_ref_root
|
|
23
|
+
"""
|
|
24
|
+
from __future__ import annotations
|
|
25
|
+
|
|
26
|
+
import os
|
|
27
|
+
import shutil
|
|
28
|
+
import sys
|
|
29
|
+
import tempfile
|
|
30
|
+
|
|
31
|
+
from . import corpus, tokens
|
|
32
|
+
from .mdcg import MdCG
|
|
33
|
+
from .mcp_server import call_tool
|
|
34
|
+
from .security import AccessDenied
|
|
35
|
+
|
|
36
|
+
PASS = FAIL = 0
|
|
37
|
+
FAILS = []
|
|
38
|
+
|
|
39
|
+
SECRET_TEXT = ("AKIAIOSFODNN7EXAMPLE-DUMMY\n" # 哑数据,非真实凭据
|
|
40
|
+
"secret-line-2=dummy\nsecret-line-3=dummy\n")
|
|
41
|
+
ALPHA_TEXT = '""" 供能注释。"""\n\ndef compute(mass):\n return mass\n'
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def check(name, cond, detail=""):
|
|
45
|
+
global PASS, FAIL
|
|
46
|
+
if cond:
|
|
47
|
+
PASS += 1
|
|
48
|
+
print(f" [PASS] {name}" + (f" · {detail}" if detail else ""))
|
|
49
|
+
else:
|
|
50
|
+
FAIL += 1
|
|
51
|
+
FAILS.append(name)
|
|
52
|
+
print(f" [FAIL] {name} · {detail}")
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def denied(fn):
|
|
56
|
+
"""断言 fn 被拒:抛 PermissionError,或返回 ok=False。"""
|
|
57
|
+
try:
|
|
58
|
+
out = fn()
|
|
59
|
+
return out.get("ok") is False, f"returned ok={out.get('ok')}"
|
|
60
|
+
except PermissionError as exc:
|
|
61
|
+
return True, f"PermissionError({str(exc)[:40]}…)"
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def main():
|
|
65
|
+
print("=" * 68)
|
|
66
|
+
print("md_cg P1-X 验收 · op=ref/index_code/index_doc 根白名单(三形态防越权读)")
|
|
67
|
+
print("=" * 68)
|
|
68
|
+
|
|
69
|
+
tmp = tempfile.mkdtemp(prefix="mdcg_p1x_")
|
|
70
|
+
memroot = os.path.join(tmp, "memroot") # 认知图根(服务器侧)
|
|
71
|
+
allow = os.path.join(tmp, "allow") # 部署白名单内的代码目录
|
|
72
|
+
victim = os.path.join(tmp, "victim") # 白名单外(宿主敏感区模拟)
|
|
73
|
+
os.makedirs(allow)
|
|
74
|
+
os.makedirs(victim)
|
|
75
|
+
with open(os.path.join(victim, "secret.txt"), "w", encoding="utf-8") as f:
|
|
76
|
+
f.write(SECRET_TEXT)
|
|
77
|
+
with open(os.path.join(allow, "alpha.py"), "w", encoding="utf-8") as f:
|
|
78
|
+
f.write(ALPHA_TEXT)
|
|
79
|
+
|
|
80
|
+
env = "MDCG_INGEST_ROOT"
|
|
81
|
+
old = os.environ.get(env)
|
|
82
|
+
os.environ[env] = allow # 部署声明:只有 allow/ 可读入
|
|
83
|
+
|
|
84
|
+
corpus.reset_root(memroot)
|
|
85
|
+
cg = MdCG(memroot)
|
|
86
|
+
full = {"lineno": 1, "end": 99} # 无 hash → 不做漂移校验直读
|
|
87
|
+
|
|
88
|
+
try:
|
|
89
|
+
print("\n【1】三形态越权读必须被拒(fail-closed)")
|
|
90
|
+
ok, d = denied(lambda: call_tool(cg, "cg", {
|
|
91
|
+
"op": "ref", "ref": dict(path="secret.txt", root=victim, **full)}))
|
|
92
|
+
check("①a 自报 root 越界被拒(secret 不进上下文)", ok, d)
|
|
93
|
+
ok, d = denied(lambda: call_tool(cg, "cg", {
|
|
94
|
+
"op": "ref", "root": allow,
|
|
95
|
+
"ref": dict(path=os.path.join(victim, "secret.txt"), **full)}))
|
|
96
|
+
check("①b ref.path 绝对路径被拒(join 丢弃 root 也拦)", ok, d)
|
|
97
|
+
ok, d = denied(lambda: call_tool(cg, "cg", {
|
|
98
|
+
"op": "ref", "root": allow,
|
|
99
|
+
"ref": dict(path=os.path.join("..", "victim", "secret.txt"),
|
|
100
|
+
**full)}))
|
|
101
|
+
check("①c '../' 上跳被拒", ok, d)
|
|
102
|
+
|
|
103
|
+
print("\n【2】同族:index_code / index_doc 越界 path 必须被拒")
|
|
104
|
+
ok, d = denied(lambda: call_tool(cg, "cg", {"op": "index_code",
|
|
105
|
+
"path": victim}))
|
|
106
|
+
check("②a index_code 越界 path 被拒", ok, d)
|
|
107
|
+
ok, d = denied(lambda: call_tool(cg, "cg", {"op": "index_doc",
|
|
108
|
+
"path": victim}))
|
|
109
|
+
check("②b index_doc 越界 path 被拒", ok, d)
|
|
110
|
+
|
|
111
|
+
print("\n【3】白名单内不误伤")
|
|
112
|
+
out = call_tool(cg, "cg", {"op": "index_code", "path": allow})
|
|
113
|
+
nid = (out.get("ids") or [None])[0]
|
|
114
|
+
rr = call_tool(cg, "cg", {"op": "ref", "node_id": nid}) if nid \
|
|
115
|
+
else {"ok": False, "error": "no ids"}
|
|
116
|
+
check("③a 白名单内索引 + node 回读正常",
|
|
117
|
+
out.get("ok") and out.get("indexed", 0) >= 1
|
|
118
|
+
and rr.get("ok") is True and "compute" in (rr.get("text") or ""),
|
|
119
|
+
f"indexed={out.get('indexed')} ref_ok={rr.get('ok')}")
|
|
120
|
+
rr = call_tool(cg, "cg", {"op": "ref", "root": allow,
|
|
121
|
+
"ref": dict(path="alpha.py", lineno=1, end=2)})
|
|
122
|
+
check("③b 白名单内 inline ref 回读正常", rr.get("ok") is True,
|
|
123
|
+
f"ok={rr.get('ok')} err={rr.get('error')}")
|
|
124
|
+
|
|
125
|
+
print("\n【4】先例与开关语义不回归")
|
|
126
|
+
ok, d = denied(lambda: call_tool(cg, "cg", {
|
|
127
|
+
"op": "ingest", "action": "file",
|
|
128
|
+
"path": os.path.join(victim, "secret.txt")}))
|
|
129
|
+
check("④a ingest 越界仍被 P1-4 拦(先例闸不回归)", ok, d)
|
|
130
|
+
os.environ.pop(env, None)
|
|
131
|
+
rr = call_tool(cg, "cg", {
|
|
132
|
+
"op": "ref", "ref": dict(path="secret.txt", root=victim, **full)})
|
|
133
|
+
check("④b env 未设 = 部署开关放开(默认行为不变)",
|
|
134
|
+
rr.get("ok") is True
|
|
135
|
+
and "AKIAIOSFODNN7EXAMPLE" in (rr.get("text") or ""),
|
|
136
|
+
f"ok={rr.get('ok')}")
|
|
137
|
+
try:
|
|
138
|
+
tokens.Principal(role="guest", ops_allow=("read",), theory_ok=True
|
|
139
|
+
).require_op("ref")
|
|
140
|
+
ok, d = False, "guest 未被拒"
|
|
141
|
+
except AccessDenied:
|
|
142
|
+
ok, d = True, "AccessDenied"
|
|
143
|
+
check("④c guest 令牌 op=ref 仍被 require_op 拒", ok, d)
|
|
144
|
+
finally:
|
|
145
|
+
if old is None:
|
|
146
|
+
os.environ.pop(env, None)
|
|
147
|
+
else:
|
|
148
|
+
os.environ[env] = old
|
|
149
|
+
corpus.reset_root(memroot) # 收尾:指向本次临时根
|
|
150
|
+
shutil.rmtree(tmp, ignore_errors=True)
|
|
151
|
+
|
|
152
|
+
print("\n" + "=" * 68)
|
|
153
|
+
print(f"P1-X 根白名单守卫: {PASS}/{PASS + FAIL} 通过")
|
|
154
|
+
if FAILS:
|
|
155
|
+
print("未过:" + ";".join(FAILS))
|
|
156
|
+
return 0 if FAIL == 0 else 1
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
if __name__ == "__main__":
|
|
160
|
+
sys.exit(main())
|