@furongjun1999/dsh-memory 0.7.2 → 0.7.4

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 (129) hide show
  1. package/README.md +57 -47
  2. package/codebuddy/CODEBUDDY.md +6 -6
  3. package/docs/README.md +148 -144
  4. package/docs/discipline/harnesses.yaml +16 -8
  5. package/docs/discipline/templates/zcode-user.md.tmpl +49 -0
  6. package/docs/eval/AGI/344/270/203/347/273/264/350/257/204/345/210/206/346/212/245/345/221/212_/345/205/255/345/256/266/350/256/260/345/277/206/347/263/273/347/273/237/345/220/214/345/260/272/345/256/236/346/265/213_v3.1.md +340 -0
  7. package/docs/eval/N225_/347/264/242/345/274/225/346/227/245/345/277/227/351/235/236/345/257/271/350/261/241/350/243/205/350/275/275/351/235/242/347/261/273/345/236/213/351/227/270_v1.0.md +2 -2
  8. package/docs/eval/cons200_/345/206/262/347/252/201/346/243/200/346/265/213/351/200/211/351/235/242_/345/256/236/346/226/275/350/256/260/345/275/225_v1.0.md +1 -1
  9. package/docs/eval/cons200_/345/206/262/347/252/201/346/243/200/346/265/213/351/200/211/351/235/242_/345/256/236/346/226/275/350/256/260/345/275/225_v1.1.md +1 -1
  10. package/docs/eval/issue43_/351/273/230/350/256/244/347/255/226/347/225/245/344/270/216/351/224/256/347/261/273/345/236/213/351/227/270_v1.1.md +1 -1
  11. package/docs/eval/issue43_/351/273/230/350/256/244/347/255/226/347/225/245/345/212/240/350/275/275/344/270/216/345/207/255/346/215/256/346/230/216/346/226/207/351/230/237/345/210/227_v1.0.md +2 -2
  12. package/docs/eval/issue50_/345/205/203/346/225/260/346/215/256/351/200/217/344/274/240/344/270/216/345/205/234/345/272/225_/344/277/256/345/244/215/350/256/260/345/275/225_v1.0.md +5 -5
  13. package/docs/eval/issue50_/345/215/212/351/207/215/345/244/215/345/276/205/345/256/232/345/244/215/346/240/270_/344/277/256/345/244/215/350/256/260/345/275/225_v1.0.md +9 -9
  14. package/docs/eval/issue50_/345/276/205/345/256/232/345/244/215/346/240/270/345/205/245/351/230/237_/344/277/256/345/244/215/350/256/260/345/275/225_v1.0.md +4 -4
  15. package/docs/eval/issue50_/351/207/215/350/246/201/345/272/246/345/220/214/346/272/220/344/270/216/344/277/235/346/212/244/350/257/255/344/271/211_/344/277/256/345/244/215/350/256/260/345/275/225_v1.0.md +1 -1
  16. package/docs/eval/issue51_/344/270/200/351/224/256/345/256/211/350/243/205/345/244/261/350/264/245_/345/275/222/345/261/236/345/210/244/345/256/232_v1.0.md +1 -1
  17. package/docs/eval/issue52_/346/235/241/344/273/266/345/205/210/350/241/214/344/270/216/346/210/252/346/226/255/345/217/257/350/247/202/346/265/213_/344/277/256/345/244/215/350/256/260/345/275/225_v1.0.md +3 -3
  18. package/docs/eval//344/270/211/346/241/243/350/207/252/346/262/273_/346/255/245/351/252/244/342/221/242/345/217/230/346/233/264/345/215/225/344/270/216/345/233/236/346/273/232/345/216/237/350/257/255_/350/220/275/347/240/201/350/256/260/345/275/225_v1.0.md +3 -3
  19. package/docs/eval//344/270/211/346/241/243/350/207/252/346/262/273_/346/255/245/351/252/244/342/221/243/345/207/206/345/205/245/350/257/273/346/225/260_/350/220/275/347/240/201/350/256/260/345/275/225_v1.0.md +7 -7
  20. package/docs/eval//344/274/230/345/214/226/347/254/254/344/270/200/346/211/271_/346/216/245/347/272/277/344/270/216/347/255/211/344/273/267/345/217/230/346/215/242_v1.0.md +2 -2
  21. package/docs/eval//344/274/230/345/214/226/347/254/254/344/270/211/346/211/271_/351/227/250/347/246/201/350/275/254/346/255/243/344/270/216/350/260/203/345/272/246/346/255/242/350/241/200/344/270/216/351/227/250/346/216/247/346/224/266/345/217/243_v1.0.md +1 -1
  22. package/docs/eval//344/274/230/345/214/226/347/254/254/344/272/214/346/211/271_/344/276/235/350/265/226/351/200/217/344/274/240/344/270/216/345/257/271/346/213/215/345/217/243/345/276/204/344/270/216/350/264/237/347/274/223/345/255/230_v1.0.md +7 -7
  23. package/docs/eval//345/207/272/350/264/247/351/235/242/345/206/222/347/203/237_/350/277/233/350/264/247/351/227/250/347/246/201_v1.0.md +10 -10
  24. package/docs/eval//345/217/221/345/270/20307_/345/244/226/351/203/250/346/212/245/345/221/212/345/233/233/346/211/271/344/277/256/345/244/215/344/270/216/346/217/222/344/273/266/351/235/242/345/212/240/345/233/272_v1.0.md +4 -0
  25. package/docs/eval//345/217/221/345/270/20308_/350/207/252/350/277/255/344/273/243/344/270/216/347/235/241/347/234/240_/345/233/276/346/243/200/347/264/242/350/267/257/344/270/216/346/235/203/351/207/215_v1.0.md +1 -1
  26. package/docs/eval//345/217/221/345/270/20311_/345/244/226/346/212/245/345/205/255/350/277/236/344/277/256/344/270/216/344/270/226/347/225/214/346/250/241/345/236/213/345/272/225/345/272/247_v1.0.md +91 -0
  27. package/docs/eval//345/217/221/345/270/20312_/344/270/226/347/225/214/346/250/241/345/236/213/345/212/237/350/203/275/347/253/257_v1.0.md +108 -0
  28. package/docs/eval//345/275/222/344/270/200/345/261/202/347/274/272/347/234/201/347/277/273/345/205/263_/344/277/256/345/244/215/350/256/260/345/275/225_v1.0.md +2 -2
  29. package/docs/eval//347/224/250/346/210/267/350/243/201/345/206/263/345/244/204/347/275/256_/347/254/254/344/270/200/346/211/271_v1.0.md +195 -0
  30. package/docs/eval//347/224/250/346/210/267/350/243/201/345/206/263/345/244/204/347/275/256_/347/254/254/344/272/214/346/211/271B6_/346/234/254/346/234/272/350/267/257/345/276/204/347/233/270/345/257/271/345/214/226_v1.0.md +78 -0
  31. 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 +1 -1
  32. 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 +3 -3
  33. package/docs/eval//347/254/2543/345/261/202stg/347/273/223/346/236/204/347/264/242/345/274/225_/345/256/236/346/226/275/350/256/260/345/275/225_v1.0.md +1 -1
  34. package/docs/eval//347/274/226/347/240/201/351/235/242/345/211/215/347/275/256_/345/205/245/345/217/243/350/207/252/344/277/235/350/257/201UTF8/344/270/216/346/226/207/346/234/254open/345/256/210/345/215/253_v1.0.md +1 -1
  35. 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_v26.md +196 -0
  36. 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_v27.md +259 -0
  37. 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_v28.md +217 -0
  38. 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_v29.md +270 -0
  39. 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_v30.md +231 -0
  40. 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_v31.md +281 -0
  41. package/docs/eval//350/257/255/344/271/211/346/227/266/347/251/272/345/233/276/350/241/245/345/205/250_P1_/346/212/275/345/217/226/345/231/250v4_/344/270/211/347/216/207/350/257/273/346/225/260_v1.0.md +231 -0
  42. package/docs/hive//345/256/211/345/205/250/345/256/241/350/256/241/345/256/236/351/224/232_v0.1.md +1 -1
  43. package/docs/hive//350/234/202/345/267/242M6_ingest/345/256/236/346/226/275/350/256/241/345/210/222_v0.1.md +1 -1
  44. 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 +1 -1
  45. package/docs/hive//350/234/202/345/267/242/350/256/276/350/256/241_/347/220/206/350/256/272/345/257/271/351/275/220_v0.1.md +17 -17
  46. package/docs/hive//350/234/202/345/267/242/350/277/255/344/273/243_/345/256/217/350/247/202/344/270/216/347/276/244/344/275/223/350/260/203/345/272/246_v0.1.md +1 -1
  47. package/docs/mdcg/README/350/257/246/347/273/206/347/211/210_v0.4.10.md +2 -2
  48. package/docs/mdcg//344/270/226/347/225/214/346/250/241/345/236/213/345/212/237/350/203/275/347/253/257_/344/275/277/347/224/250/344/270/216/350/277/220/347/273/264_v1.0.md +305 -0
  49. 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 +45 -42
  50. package/docs/mdcg//345/217/221/345/270/203/351/227/250/347/246/201/351/223/276_v0.1.md +29 -8
  51. package/docs/mdcg//347/235/241/347/234/240/345/221/250/346/234/237_/350/277/220/347/273/264/345/211/215/346/217/220/344/270/216/347/273/264/346/212/244/346/214/207/345/215/227_v1.0.md +71 -1
  52. package/docs/plans//345/205/250/344/270/255/346/226/207/347/274/226/347/240/201/344/270/216/350/234/202/345/267/242/344/273/273/345/212/241/346/240/207/350/257/206/345/245/221/347/272/246_v2.0.md +1 -1
  53. package/docs/plans//345/244/232/344/270/273/344/275/223/344/270/226/347/225/214/346/250/241/345/236/213_/345/257/271/351/275/220/350/257/204/344/274/260/344/270/216/350/220/275/345/234/260/350/256/276/350/256/241_v0.1.md +141 -0
  54. package/docs/plans//347/235/241/347/234/240/344/270/216/350/207/252/350/277/255/344/273/243_/345/212/237/350/203/275/344/274/230/345/214/226/350/256/276/350/256/241_v0.4.md +2 -2
  55. package/docs/plans//350/257/255/344/271/211/346/227/266/347/251/272/345/233/276/350/241/245/345/205/250_/344/270/226/347/225/214/346/250/241/345/236/213/345/212/237/350/203/275/347/253/257_/350/256/276/350/256/241_v0.1.md +107 -0
  56. package/docs//345/267/245/344/275/234/347/272/252/345/276/213_/350/256/244/347/237/245/345/233/276/346/235/241/347/233/256_v1.1.json +6 -5
  57. package/docs//347/247/244_/350/256/260/345/277/206/347/263/273/347/273/237/350/257/204/346/265/213/350/247/204/350/214/203_v2.1.md +225 -0
  58. package/dsh/cordis-patch-profile-web.example.yml +2 -2
  59. package/lib/bridge.js +9 -0
  60. package/lib/hooks.d.ts +8 -1
  61. package/lib/hooks.js +134 -50
  62. package/lib/lib/hook_audit.d.ts +55 -0
  63. package/lib/lib/hook_audit.js +208 -0
  64. package/lib/lib/mutual.js +5 -1
  65. package/lib/lib/roleplay_web.js +17 -2
  66. package/lib/lib/session_state.d.ts +56 -0
  67. package/lib/lib/session_state.js +124 -0
  68. package/lib/tools.js +12 -1
  69. package/md_cg/auditview.py +248 -0
  70. package/md_cg/bench_e2e_judge.py +4 -2
  71. package/md_cg/branches.py +29 -3
  72. package/md_cg/consistency.py +38 -13
  73. package/md_cg/datapath.py +38 -11
  74. package/md_cg/forgetting.py +15 -2
  75. package/md_cg/freshness.py +32 -11
  76. package/md_cg/ghostref.py +130 -0
  77. package/md_cg/judgment_manifest.py +7 -0
  78. package/md_cg/lifecycle.py +38 -0
  79. package/md_cg/mcp_server.py +122 -12
  80. package/md_cg/mdcg.py +4923 -4822
  81. package/md_cg/mdcos.py +109 -21
  82. package/md_cg/nodefile.py +77 -13
  83. package/md_cg/readcache.py +29 -4
  84. package/md_cg/selfreport.py +12 -3
  85. package/md_cg/sleep.py +129 -13
  86. package/md_cg/sources.py +1 -1
  87. package/md_cg/state_events.py +131 -0
  88. package/md_cg/state_slots.py +221 -0
  89. package/md_cg/stg.py +68 -3
  90. package/md_cg/sustain.py +1436 -1436
  91. package/md_cg/test_auditview.py +277 -0
  92. package/md_cg/test_autonomy_modes.py +2 -1
  93. package/md_cg/test_boot_openblas_guard.py +197 -0
  94. package/md_cg/test_ccg_form_parity.py +95 -4
  95. package/md_cg/test_cons200_scan_selection.py +4 -2
  96. package/md_cg/test_datapath_device_name.py +62 -3
  97. package/md_cg/test_generation_guard.py +5 -2
  98. package/md_cg/test_ghostref.py +182 -0
  99. package/md_cg/test_interop.py +1 -1
  100. package/md_cg/test_issue52_scan_condition_first.py +1 -1
  101. package/md_cg/test_lifecycle_retire_leak.py +408 -0
  102. package/md_cg/test_lock.py +16 -7
  103. package/md_cg/test_m3_h9_semantic_guard.py +1 -1
  104. package/md_cg/test_n230_dirty_replay.py +375 -375
  105. package/md_cg/test_n238_body_text_parity.py +156 -0
  106. package/md_cg/test_n276_probe_hoist.py +199 -0
  107. package/md_cg/test_p4_freshness.py +95 -1
  108. package/md_cg/test_policy_required_ccg.py +3 -1
  109. package/md_cg/test_read_face_semantics.py +6 -3
  110. package/md_cg/test_readcache_prodpath.py +66 -0
  111. package/md_cg/test_sleep.py +58 -1
  112. package/md_cg/test_sleep_p1.py +218 -2
  113. package/md_cg/test_state_event_op.py +514 -0
  114. package/md_cg/test_state_events.py +178 -0
  115. package/md_cg/test_state_slots.py +691 -0
  116. package/md_cg/test_time_core_lint.py +8 -1
  117. package/md_cg/test_writepipe.py +8 -5
  118. package/md_cg/tokens.py +18 -2
  119. package/md_cg/writepipe.py +76 -0
  120. package/package.json +2 -2
  121. package/skills/plugin.json +1 -1
  122. package/src/bridge.ts +9 -0
  123. package/src/hooks.ts +599 -517
  124. package/src/lib/hook_audit.ts +243 -0
  125. package/src/lib/mutual.ts +5 -1
  126. package/src/lib/roleplay_web.ts +17 -2
  127. package/src/lib/session_state.ts +127 -0
  128. package/src/tools.ts +12 -1
  129. package/zcode/AGENTS.md +6 -6
@@ -0,0 +1,178 @@
1
+ # -*- coding: utf-8 -*-
2
+ """test_state_events · 状态事件账本(append-only)+检验强度字段(check_strength)
3
+
4
+ 多主体世界模型对齐 v0.1 §2(L0「事件必记账」/ L1「检验强度」)落地的行为守卫。
5
+
6
+ 运行:python -m md_cg.test_state_events
7
+ """
8
+ from __future__ import annotations
9
+
10
+ import json
11
+ import os
12
+ import tempfile
13
+
14
+ from . import state_events
15
+ from .mdcos import MdCGOS
16
+ from .writepipe import _AUTONOMY_META_KEYS, default_pipeline
17
+
18
+ _ok = 0
19
+ _fail = []
20
+
21
+
22
+ def check(name, cond, detail=""):
23
+ global _ok
24
+ if cond:
25
+ _ok += 1
26
+ print("[ok] " + name)
27
+ else:
28
+ _fail.append(name)
29
+ print("[FAIL] %s · %s" % (name, str(detail)[:240]))
30
+
31
+
32
+ def _dump(r):
33
+ return json.dumps(r, sort_keys=True, ensure_ascii=False)
34
+
35
+
36
+ def main():
37
+ tmp = tempfile.mkdtemp(prefix="mdcg_se_test_")
38
+ cg = MdCGOS(os.path.join(tmp, "root"))
39
+
40
+ # ---- 1. append 与读回(落盘序)----
41
+ state_events.append(cg, "鲸娘", "住所", old="帐篷", new="海景别墅",
42
+ kind="migration", seq=553, evidence="用户侧 r0553")
43
+ state_events.append(cg, "鲸娘", "房贷", old="有", new=None,
44
+ kind="retraction", seq=577, evidence="用户侧 r0577")
45
+ state_events.append(cg, "鲸娘", "烤箱", old=None, new="已启用",
46
+ kind="enablement", seq=595, evidence="AI 侧 r0595")
47
+ recs = state_events.read(cg)
48
+ check("append 3 条 → read 回 3 条", len(recs) == 3, len(recs))
49
+ check("落盘序保持(首条=迁移)", recs and recs[0]["kind"] == "migration",
50
+ recs[0] if recs else None)
51
+ check("五元在场", bool(recs) and all(
52
+ k in recs[0] for k in ("subject", "slot", "old", "new", "seq", "evidence")),
53
+ sorted(recs[0].keys()) if recs else None)
54
+
55
+ # ---- 2. append-only 不覆盖(连写后旧记录逐条原样)----
56
+ before = [_dump(r) for r in recs]
57
+ state_events.append(cg, "鲸娘", "住所", old="海景别墅", new="海边小屋",
58
+ kind="migration", seq=700, evidence="r0700")
59
+ after = state_events.read(cg)
60
+ check("追加不覆盖(4 条)", len(after) == 4, len(after))
61
+ check("旧 3 条逐条原样", [_dump(r) for r in after[:3]] == before)
62
+
63
+ # ---- 3. 重启(新实例)读回 ----
64
+ cg2 = MdCGOS(cg.root)
65
+ check("新实例读回 4 条", len(state_events.read(cg2)) == 4)
66
+
67
+ # ---- 4. 过滤与 limit ----
68
+ check("按 slot 过滤", len(state_events.read(cg, slot="住所")) == 2)
69
+ check("按 kind 过滤", len(state_events.read(cg, kind="retraction")) == 1)
70
+ check("limit 取末 2 条", len(state_events.read(cg, limit=2)) == 2)
71
+ check("limit 末条为最后写入", state_events.read(cg, limit=1)[0]["seq"] == 700)
72
+
73
+ # ---- 5. 参数校验(fail-closed)----
74
+ # 注:空 subject/空白 slot 两用例须带 new="v"——否则同时命中「old/new 同空」
75
+ # 校验(2026-10-05 复核:无判别力断言,删目标校验后仍照绿)。
76
+ # 独立库:拒绝用例若在某处校验被误删的变异态下真落盘,只污染本库,
77
+ # 不波及第 6 段条数统计(编排侧变异自证:1 变异 → 1 红的干净定点)。
78
+ bad_root = MdCGOS(os.path.join(tmp, "bad_root"))
79
+ for bad, nm in [
80
+ (dict(subject="", slot="x", new="v"), "空 subject 拒绝"),
81
+ (dict(subject="x", slot=" ", new="v"), "空白 slot 拒绝"),
82
+ (dict(subject="x", slot="y", old=None, new=None), "old/new 同空拒绝"),
83
+ ]:
84
+ try:
85
+ state_events.append(bad_root, **bad)
86
+ check(nm, False, "未抛 ValueError")
87
+ except ValueError:
88
+ check(nm, True)
89
+ try:
90
+ state_events.append(bad_root, "x", "y", new="v", kind="teleport")
91
+ check("未知 kind 拒绝", False, "未抛 ValueError")
92
+ except ValueError:
93
+ check("未知 kind 拒绝", True)
94
+
95
+ # ---- 6. 坏行容忍(跳过 + 记账 + 不中断 + 样本有界)----
96
+ # 坏行数(12)须**越过** _BAD_ROW_SAMPLE_CAP(8):只造 2 行时
97
+ # `len(samples) <= cap` 是平凡真(空列表也满足),且删掉记录逻辑后
98
+ # 仍全绿——无判别力(2026-10-05 复核 NEW-red 实证)。故断言取
99
+ # **精确等式** `min(前值+12, cap)` 且要求 >0:既抓「不记录」也抓「无界」。
100
+ p = state_events.ledger_path(cg)
101
+ bad_lines = 12
102
+ with open(p, "a", encoding="utf-8") as f:
103
+ f.write("{broken json\n")
104
+ f.write("[1, 2, 3]\n")
105
+ for i in range(bad_lines - 2):
106
+ f.write("not-json-%d\n" % i)
107
+ n0 = state_events.BAD_ROWS
108
+ s0 = len(state_events._BAD_ROW_SAMPLES)
109
+ recs2 = state_events.read(cg)
110
+ check("坏行跳过后好行全在", len(recs2) == 4, len(recs2))
111
+ check("坏行记账(+%d)" % bad_lines, state_events.BAD_ROWS == n0 + bad_lines,
112
+ state_events.BAD_ROWS - n0)
113
+ _cap = state_events._BAD_ROW_SAMPLE_CAP
114
+ _want = min(s0 + bad_lines, _cap)
115
+ check("坏行样本有界(cap %d,期望 %d,实际 %d)"
116
+ % (_cap, _want, len(state_events._BAD_ROW_SAMPLES)),
117
+ len(state_events._BAD_ROW_SAMPLES) == _want
118
+ and len(state_events._BAD_ROW_SAMPLES) > 0,
119
+ len(state_events._BAD_ROW_SAMPLES))
120
+
121
+ # ---- 7. check_strength 字段(缺省零迁移 / 非法拒绝)----
122
+ cg.add("cs_a", "# 功能名:断言甲\n# 生效条件:测\n", layer="knowledge",
123
+ verification_basis="test", check_strength="hoop")
124
+ fm_a = (cg.get("cs_a") or {}).get("frontmatter") or {}
125
+ check("带 check_strength 落 fm", fm_a.get("check_strength") == "hoop",
126
+ fm_a.get("check_strength"))
127
+ cg.add("cs_b", "# 功能名:断言乙\n# 生效条件:测\n", layer="knowledge",
128
+ verification_basis="test")
129
+ fm_b = (cg.get("cs_b") or {}).get("frontmatter") or {}
130
+ check("缺省不落键(存量零迁移)", "check_strength" not in fm_b,
131
+ fm_b.get("check_strength"))
132
+ try:
133
+ cg.add("cs_c", "# 功能名:断言丙\n# 生效条件:测\n", layer="knowledge",
134
+ verification_basis="test", check_strength="nuke")
135
+ check("非法强度拒绝", False, "未抛 ValueError")
136
+ except ValueError:
137
+ check("非法强度拒绝", True)
138
+
139
+ # ---- 8. 覆写继承(全量重建 fm 的坑)----
140
+ cg.add("cs_a", "# 功能名:断言甲\n# 生效条件:测(覆写)\n", layer="knowledge",
141
+ verification_basis="test", override=True)
142
+ fm_a2 = (cg.get("cs_a") or {}).get("frontmatter") or {}
143
+ check("覆写默认继承", fm_a2.get("check_strength") == "hoop",
144
+ fm_a2.get("check_strength"))
145
+ cg.add("cs_a", "# 功能名:断言甲\n# 生效条件:测(再覆写)\n",
146
+ layer="knowledge", verification_basis="test", override=True,
147
+ check_strength="doubly_decisive")
148
+ fm_a3 = (cg.get("cs_a") or {}).get("frontmatter") or {}
149
+ check("覆写显式改值", fm_a3.get("check_strength") == "doubly_decisive",
150
+ fm_a3.get("check_strength"))
151
+
152
+ # ---- 9. 写链透传(A1 补接,2026-10-05:经路线 C 的 audit 现值面发现
153
+ # 写链实参表漏传 check_strength——经 MCP op=write 声明一律静默丢弃,
154
+ # 与 B2 sensitivity 漏传同族。此处钉住「写链透传」与「变更单载荷白名单」
155
+ # 两个面,防复发。)----
156
+ _pipe = default_pipeline()
157
+ _o = _pipe.execute(cg, {
158
+ "op": "write", "node_id": "cs_wire",
159
+ "content": "# 功能名:写链透传\n# 生效条件:测\n# 子功能:无\n"
160
+ "# 执行:无\n# 验证方式:test\n# 不适用条件:无\n",
161
+ "layer": "knowledge", "content_kind": "text",
162
+ "verification_basis": "test", "check_strength": "smoking_gun"})
163
+ fm_w = (cg.get("cs_wire") or {}).get("frontmatter") or {}
164
+ check("写链透传 check_strength(A1 补接)",
165
+ _o.get("committed") is True
166
+ and fm_w.get("check_strength") == "smoking_gun",
167
+ (_o.get("committed"), fm_w.get("check_strength")))
168
+ check("变更单载荷白名单含 check_strength(A1 补接)",
169
+ "check_strength" in _AUTONOMY_META_KEYS,
170
+ list(_AUTONOMY_META_KEYS))
171
+
172
+ print("\ntest_state_events: %d 通过 / %d 失败" % (_ok, len(_fail)))
173
+ if _fail:
174
+ raise SystemExit(1)
175
+
176
+
177
+ if __name__ == "__main__":
178
+ main()