@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
package/lib/lib/token_store.d.ts
CHANGED
|
@@ -25,7 +25,13 @@ export interface ResolveTokenOptions {
|
|
|
25
25
|
/** 密钥环路径覆盖(默认 ~/.mdcg/token)。 */
|
|
26
26
|
keyringPath?: string;
|
|
27
27
|
}
|
|
28
|
-
/**
|
|
28
|
+
/** 辅助存储根(密钥/令牌/信任/理论/心跳):与 md_cg 的 `datapath.aux_root()` 同口径。
|
|
29
|
+
*
|
|
30
|
+
* 默认 `~/.mdcg`(历史值,**逐字保留**——改默认会让存量密钥/令牌失联);
|
|
31
|
+
* `MDCG_AUX_ROOT` 可把它们整体搬走(沙箱/多用户/与记忆真源同处的场景)。
|
|
32
|
+
* 与 `config.mdcg.root`(记忆真源)有意分离:身份与信任不随认知图迁移。 */
|
|
33
|
+
export declare function auxRoot(): string;
|
|
34
|
+
/** 默认密钥环路径:与 md_cg 的 `_tokens.json` 同目录(aux 根下,见 auxRoot())。 */
|
|
29
35
|
export declare function defaultKeyringPath(): string;
|
|
30
36
|
/**
|
|
31
37
|
* 解析写入凭据:显式配置 → 进程 env → 密钥环 → 首启自动签发。
|
package/lib/lib/token_store.js
CHANGED
|
@@ -29,11 +29,20 @@
|
|
|
29
29
|
import { spawnSync } from 'node:child_process';
|
|
30
30
|
import { chmodSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
31
31
|
import { homedir } from 'node:os';
|
|
32
|
-
import { dirname, join } from 'node:path';
|
|
32
|
+
import { dirname, join, resolve } from 'node:path';
|
|
33
33
|
import { pythonPathValue, runRoot } from './datapath.js';
|
|
34
|
-
/**
|
|
34
|
+
/** 辅助存储根(密钥/令牌/信任/理论/心跳):与 md_cg 的 `datapath.aux_root()` 同口径。
|
|
35
|
+
*
|
|
36
|
+
* 默认 `~/.mdcg`(历史值,**逐字保留**——改默认会让存量密钥/令牌失联);
|
|
37
|
+
* `MDCG_AUX_ROOT` 可把它们整体搬走(沙箱/多用户/与记忆真源同处的场景)。
|
|
38
|
+
* 与 `config.mdcg.root`(记忆真源)有意分离:身份与信任不随认知图迁移。 */
|
|
39
|
+
export function auxRoot() {
|
|
40
|
+
const env = (process.env.MDCG_AUX_ROOT ?? '').trim();
|
|
41
|
+
return env ? resolve(env) : join(homedir(), '.mdcg');
|
|
42
|
+
}
|
|
43
|
+
/** 默认密钥环路径:与 md_cg 的 `_tokens.json` 同目录(aux 根下,见 auxRoot())。 */
|
|
35
44
|
export function defaultKeyringPath() {
|
|
36
|
-
return join(
|
|
45
|
+
return join(auxRoot(), 'token');
|
|
37
46
|
}
|
|
38
47
|
/** 读取密钥环;不存在 / 不可读 / 空文件一律返回 undefined(不抛异常)。 */
|
|
39
48
|
function readKeyring(path) {
|
package/md_cg/audit.py
CHANGED
|
@@ -168,7 +168,9 @@ def _verify_code(payload, ctx):
|
|
|
168
168
|
return _verdict(REJECT, "code", f"语法错误 L{exc.lineno}: {exc.msg}")
|
|
169
169
|
n_def = sum(isinstance(x, (ast.FunctionDef, ast.AsyncFunctionDef, ast.ClassDef))
|
|
170
170
|
for x in ast.walk(tree))
|
|
171
|
-
|
|
171
|
+
# P2-18(批次 30,外部审查报告):test_cmd 只允许服务端 env 配置——
|
|
172
|
+
# payload 是模型可控输入面,一旦接到工具参数顶层即为 RCE 注入点。
|
|
173
|
+
cmd = os.environ.get("MDCG_CODE_TEST_CMD")
|
|
172
174
|
if not cmd:
|
|
173
175
|
return _verdict(ACCEPT, "code",
|
|
174
176
|
f"AST 解析通过({n_def} 个定义);未配置 test_cmd,仅静态验证")
|
|
@@ -323,7 +325,15 @@ def load_external_verifiers(modules=None, strict=False):
|
|
|
323
325
|
if spec is None:
|
|
324
326
|
spec = os.environ.get(VERIFIER_MODULES_ENV) or ""
|
|
325
327
|
names = [x.strip() for x in str(spec).split(",") if x.strip()]
|
|
328
|
+
# P2-19(批次 30):模块名格式白名单——拒绝空串外的异常形态(路径分隔/
|
|
329
|
+
# 通配/扩展名等非 import 路径输入),加载动作本身写 stderr(可见性)。
|
|
330
|
+
import re as _re
|
|
331
|
+
_bad = [n for n in names if not _re.match(r"^[A-Za-z_][A-Za-z0-9_.]*$", n)]
|
|
326
332
|
rep = {"loaded": [], "failed": [], "verifiers": {}}
|
|
333
|
+
for n in _bad:
|
|
334
|
+
names.remove(n)
|
|
335
|
+
rep["failed"].append({"module": n,
|
|
336
|
+
"error": "模块名不符合 import 路径格式(P2-19 白名单)"})
|
|
327
337
|
if not names:
|
|
328
338
|
return rep
|
|
329
339
|
this = _sys.modules[__name__]
|
|
@@ -336,6 +346,7 @@ def load_external_verifiers(modules=None, strict=False):
|
|
|
336
346
|
if strict:
|
|
337
347
|
raise
|
|
338
348
|
continue
|
|
349
|
+
_sys.stderr.write("[mdcg-audit] 已加载外部验证器模块: %s\n" % name)
|
|
339
350
|
fn = getattr(mod, "register", None)
|
|
340
351
|
if callable(fn):
|
|
341
352
|
try:
|
package/md_cg/backfill.py
CHANGED
|
@@ -51,6 +51,7 @@ from . import crypto, nodefile, tokens
|
|
|
51
51
|
from .consolidate import _has_ccg_line, _upsert_ccg_line
|
|
52
52
|
from .fsutil import append_jsonl, read_jsonl
|
|
53
53
|
from .mdcos import MdCGOS, _ccg_field
|
|
54
|
+
from .readcache import direct_read
|
|
54
55
|
|
|
55
56
|
# ---- 常量 ----------------------------------------------------------------
|
|
56
57
|
|
|
@@ -293,7 +294,7 @@ def _readable_guard(cg, e) -> bool:
|
|
|
293
294
|
# 生效条件:仅当 cg 对 e 读出的 fm 非 None、content 未被 crypto.is_encrypted、e['layer'] 不在 SKIP_LAYERS 且 fm.get('tags') 无命中 SKIP_TAGS、ccg_completeness(content)['complete'] 为假时才继续——derive_fields(受 basis_text 影响)过滤掉 content 已有 CCG 行的可写字段为空时按 placeholder_out 是否非空返回 ('placeholder'/'unfillable', None),非空时返回 ('', item)(item 的 id 取 nid、class 依 undeducible 是否为空取 'backfillable' 或 'partial');上述四个前置不满足时依次返回 ('unreadable'/'locked'/'derived'/'present', None)。
|
|
294
295
|
def _classify(cg, e, nid, basis_text=None):
|
|
295
296
|
"""→ (skip_reason, item);skip_reason 非空表示不参与回填。"""
|
|
296
|
-
fm, content = cg
|
|
297
|
+
fm, content = direct_read(cg, e)
|
|
297
298
|
if fm is None:
|
|
298
299
|
return "unreadable", None
|
|
299
300
|
if crypto.is_encrypted(content):
|
|
@@ -421,7 +422,7 @@ def apply(x, ids=None, entry_ids=None, layer=None, limit=None,
|
|
|
421
422
|
if not e:
|
|
422
423
|
rep["skipped_drift"] += 1
|
|
423
424
|
continue
|
|
424
|
-
fm, content = cg
|
|
425
|
+
fm, content = direct_read(cg, e)
|
|
425
426
|
if fm is None or crypto.is_encrypted(content):
|
|
426
427
|
rep["skipped_locked"] += 1
|
|
427
428
|
continue
|
|
@@ -474,7 +475,7 @@ def apply(x, ids=None, entry_ids=None, layer=None, limit=None,
|
|
|
474
475
|
return rep
|
|
475
476
|
|
|
476
477
|
|
|
477
|
-
# 生效条件:x 经 _as_cg 定位后读留痕日志,仅对 action=='backfill' 且(batch 为假值则不过滤 batch,否则 rec['batch']==batch)、(entry_ids 为假值则不过滤,否则 rec['entry_id'] 属于该集合)、write_id 未出现在已完成 rollback 集合中、节点命中 cg.index['nodes'] 且 cg
|
|
478
|
+
# 生效条件:x 经 _as_cg 定位后读留痕日志,仅对 action=='backfill' 且(batch 为假值则不过滤 batch,否则 rec['batch']==batch)、(entry_ids 为假值则不过滤,否则 rec['entry_id'] 属于该集合)、write_id 未出现在已完成 rollback 集合中、节点命中 cg.index['nodes'] 且 direct_read(cg, e) 的 fm 可读、字段当前 _ccg_field(content, f) 等于留痕 after 的记录执行撤销写回(before 为 None 则删该 comment 键,否则还原原值),无字段可撤销只计 conflict 不写盘,reverted 非空时 rebuild_index,结果汇总进返回的 rep。
|
|
478
479
|
def rollback(x, batch=None, entry_ids=None, actor=None) -> dict:
|
|
479
480
|
"""按留痕反向应用:撤销本批次回填(当前值 ≠ 写入值时跳过,防覆盖)。"""
|
|
480
481
|
cg = _as_cg(x)
|
|
@@ -500,7 +501,7 @@ def rollback(x, batch=None, entry_ids=None, actor=None) -> dict:
|
|
|
500
501
|
if not e:
|
|
501
502
|
rep["missing"] += 1
|
|
502
503
|
continue
|
|
503
|
-
fm, content = cg
|
|
504
|
+
fm, content = direct_read(cg, e)
|
|
504
505
|
if fm is None:
|
|
505
506
|
rep["missing"] += 1
|
|
506
507
|
continue
|
|
@@ -627,7 +628,7 @@ def cap_plan(x, layer=None, limit=None, ids=None, min_conf=0.5) -> dict:
|
|
|
627
628
|
if not _readable_guard(cg, e):
|
|
628
629
|
rep["skipped_denied"] += 1
|
|
629
630
|
continue
|
|
630
|
-
fm, content = cg
|
|
631
|
+
fm, content = direct_read(cg, e)
|
|
631
632
|
if fm is None or crypto.is_encrypted(content):
|
|
632
633
|
rep["skipped_locked"] += 1
|
|
633
634
|
continue
|
|
@@ -671,7 +672,7 @@ def cap_apply(x, ids=None, entry_ids=None, layer=None, limit=None,
|
|
|
671
672
|
if not e:
|
|
672
673
|
rep["skipped_drift"] += 1
|
|
673
674
|
continue
|
|
674
|
-
fm, content = cg
|
|
675
|
+
fm, content = direct_read(cg, e)
|
|
675
676
|
if fm is None or crypto.is_encrypted(content):
|
|
676
677
|
rep["skipped_locked"] += 1
|
|
677
678
|
continue
|
|
@@ -725,7 +726,7 @@ def cap_rollback(x, batch=None, entry_ids=None, actor=None) -> dict:
|
|
|
725
726
|
if not e:
|
|
726
727
|
rep["missing"] += 1
|
|
727
728
|
continue
|
|
728
|
-
fm, content = cg
|
|
729
|
+
fm, content = direct_read(cg, e)
|
|
729
730
|
if fm is None:
|
|
730
731
|
rep["missing"] += 1
|
|
731
732
|
continue
|
|
@@ -798,7 +799,7 @@ def exempt_plan(x, layer=None, limit=None, ids=None, require_ready=True,
|
|
|
798
799
|
if not _readable_guard(cg, e):
|
|
799
800
|
rep["skipped_denied"] += 1
|
|
800
801
|
continue
|
|
801
|
-
fm, content = cg
|
|
802
|
+
fm, content = direct_read(cg, e)
|
|
802
803
|
if fm is None or crypto.is_encrypted(content):
|
|
803
804
|
rep["skipped_locked"] += 1
|
|
804
805
|
continue
|
|
@@ -859,7 +860,7 @@ def exempt_apply(x, ids=None, entry_ids=None, layer=None, limit=None,
|
|
|
859
860
|
if not e:
|
|
860
861
|
rep["skipped_drift"] += 1
|
|
861
862
|
continue
|
|
862
|
-
fm, content = cg
|
|
863
|
+
fm, content = direct_read(cg, e)
|
|
863
864
|
if fm is None or crypto.is_encrypted(content):
|
|
864
865
|
rep["skipped_locked"] += 1
|
|
865
866
|
continue
|
|
@@ -917,7 +918,7 @@ def exempt_rollback(x, batch=None, entry_ids=None, actor=None) -> dict:
|
|
|
917
918
|
if not e:
|
|
918
919
|
rep["missing"] += 1
|
|
919
920
|
continue
|
|
920
|
-
fm, content = cg
|
|
921
|
+
fm, content = direct_read(cg, e)
|
|
921
922
|
if fm is None:
|
|
922
923
|
rep["missing"] += 1
|
|
923
924
|
continue
|
|
@@ -973,7 +974,7 @@ def conditions_pending(x, prefix=None, layer=None, limit=None) -> dict:
|
|
|
973
974
|
if not _readable_guard(cg, e):
|
|
974
975
|
rep["skipped_denied"] += 1
|
|
975
976
|
continue
|
|
976
|
-
fm, content = cg
|
|
977
|
+
fm, content = direct_read(cg, e)
|
|
977
978
|
if fm is None or crypto.is_encrypted(content):
|
|
978
979
|
rep["skipped_locked"] += 1
|
|
979
980
|
continue
|
|
@@ -1059,7 +1060,7 @@ def fix_conditions_plan(x, prefix=None, limit=None) -> dict:
|
|
|
1059
1060
|
if not _readable_guard(cg, e):
|
|
1060
1061
|
rep["skipped_denied"] += 1
|
|
1061
1062
|
continue
|
|
1062
|
-
fm, content = cg
|
|
1063
|
+
fm, content = direct_read(cg, e)
|
|
1063
1064
|
if fm is None or crypto.is_encrypted(content):
|
|
1064
1065
|
rep["skipped_locked"] += 1
|
|
1065
1066
|
continue
|
|
@@ -1116,7 +1117,7 @@ def fix_conditions_apply(x, ids=None, entry_ids=None, prefix=None, limit=None,
|
|
|
1116
1117
|
if not e:
|
|
1117
1118
|
rep["skipped_drift"] += 1
|
|
1118
1119
|
continue
|
|
1119
|
-
fm, content = cg
|
|
1120
|
+
fm, content = direct_read(cg, e)
|
|
1120
1121
|
if fm is None or crypto.is_encrypted(content):
|
|
1121
1122
|
rep["skipped_locked"] += 1
|
|
1122
1123
|
continue
|
|
@@ -1206,7 +1207,7 @@ def fix_conditions_rollback(x, batch=None, entry_ids=None, actor=None) -> dict:
|
|
|
1206
1207
|
if not e:
|
|
1207
1208
|
rep["missing"] += 1
|
|
1208
1209
|
continue
|
|
1209
|
-
fm, content = cg
|
|
1210
|
+
fm, content = direct_read(cg, e)
|
|
1210
1211
|
if fm is None:
|
|
1211
1212
|
rep["missing"] += 1
|
|
1212
1213
|
continue
|
|
@@ -1260,7 +1261,7 @@ def verify_conditions(x, prefix=None, limit=None) -> dict:
|
|
|
1260
1261
|
continue
|
|
1261
1262
|
if e.get("layer") in INTERNAL_LAYERS:
|
|
1262
1263
|
continue
|
|
1263
|
-
fm, content = cg
|
|
1264
|
+
fm, content = direct_read(cg, e)
|
|
1264
1265
|
if fm is None or crypto.is_encrypted(content):
|
|
1265
1266
|
continue
|
|
1266
1267
|
rep["nodes_scanned"] += 1
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""bucket_zh 中文别名回填(issue #33:S1b 跨语言收敛;幂等、支持 --dry-run)。
|
|
3
|
+
|
|
4
|
+
用法:
|
|
5
|
+
python -X utf8 -m md_cg.backfill_bucket_zh --root <库根> [--dry-run] [--limit N]
|
|
6
|
+
|
|
7
|
+
为何需要:别名是**写入侧**新增元数据(英文桶键节点落 `fm.bucket_zh`),存量
|
|
8
|
+
节点没有——不回填则 S1b 对存量英文桶键仍走 cross_lang_no_match 审计兜底。
|
|
9
|
+
回填后中文 query 可收敛到英文桶(别名参与 domain_similarity,零翻译依赖)。
|
|
10
|
+
"""
|
|
11
|
+
import argparse
|
|
12
|
+
import json
|
|
13
|
+
import sys
|
|
14
|
+
|
|
15
|
+
from .mdcg import MdCG
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
# 生效条件:无条件解析参数(root 必填,dry_run/limit 可选)、以 MdCG(root) 打开库、调用 backfill_bucket_zh 并把统计 dict 以 JSON 打印,返回 0。
|
|
19
|
+
def main(argv=None):
|
|
20
|
+
ap = argparse.ArgumentParser()
|
|
21
|
+
ap.add_argument("--root", required=True, help="库根目录")
|
|
22
|
+
ap.add_argument("--dry-run", action="store_true", dest="dry_run",
|
|
23
|
+
help="只统计不改盘")
|
|
24
|
+
ap.add_argument("--limit", type=int, default=None, help="最多补写多少个节点")
|
|
25
|
+
a = ap.parse_args(argv)
|
|
26
|
+
cg = MdCG(a.root)
|
|
27
|
+
st = cg.backfill_bucket_zh(dry_run=a.dry_run, limit=a.limit)
|
|
28
|
+
print(json.dumps(st, ensure_ascii=False))
|
|
29
|
+
return 0
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
if __name__ == "__main__":
|
|
33
|
+
if hasattr(sys.stdout, "reconfigure"):
|
|
34
|
+
sys.stdout.reconfigure(encoding="utf-8")
|
|
35
|
+
sys.exit(main())
|