@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.
- package/README.md +57 -47
- package/codebuddy/CODEBUDDY.md +6 -6
- package/docs/README.md +148 -144
- package/docs/discipline/harnesses.yaml +16 -8
- package/docs/discipline/templates/zcode-user.md.tmpl +49 -0
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- package/docs/mdcg/README/350/257/246/347/273/206/347/211/210_v0.4.10.md +2 -2
- 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
- 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
- package/docs/mdcg//345/217/221/345/270/203/351/227/250/347/246/201/351/223/276_v0.1.md +29 -8
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- package/dsh/cordis-patch-profile-web.example.yml +2 -2
- package/lib/bridge.js +9 -0
- package/lib/hooks.d.ts +8 -1
- package/lib/hooks.js +134 -50
- package/lib/lib/hook_audit.d.ts +55 -0
- package/lib/lib/hook_audit.js +208 -0
- package/lib/lib/mutual.js +5 -1
- package/lib/lib/roleplay_web.js +17 -2
- package/lib/lib/session_state.d.ts +56 -0
- package/lib/lib/session_state.js +124 -0
- package/lib/tools.js +12 -1
- package/md_cg/auditview.py +248 -0
- package/md_cg/bench_e2e_judge.py +4 -2
- package/md_cg/branches.py +29 -3
- package/md_cg/consistency.py +38 -13
- package/md_cg/datapath.py +38 -11
- package/md_cg/forgetting.py +15 -2
- package/md_cg/freshness.py +32 -11
- package/md_cg/ghostref.py +130 -0
- package/md_cg/judgment_manifest.py +7 -0
- package/md_cg/lifecycle.py +38 -0
- package/md_cg/mcp_server.py +122 -12
- package/md_cg/mdcg.py +4923 -4822
- package/md_cg/mdcos.py +109 -21
- package/md_cg/nodefile.py +77 -13
- package/md_cg/readcache.py +29 -4
- package/md_cg/selfreport.py +12 -3
- package/md_cg/sleep.py +129 -13
- package/md_cg/sources.py +1 -1
- package/md_cg/state_events.py +131 -0
- package/md_cg/state_slots.py +221 -0
- package/md_cg/stg.py +68 -3
- package/md_cg/sustain.py +1436 -1436
- package/md_cg/test_auditview.py +277 -0
- package/md_cg/test_autonomy_modes.py +2 -1
- package/md_cg/test_boot_openblas_guard.py +197 -0
- package/md_cg/test_ccg_form_parity.py +95 -4
- package/md_cg/test_cons200_scan_selection.py +4 -2
- package/md_cg/test_datapath_device_name.py +62 -3
- package/md_cg/test_generation_guard.py +5 -2
- package/md_cg/test_ghostref.py +182 -0
- package/md_cg/test_interop.py +1 -1
- package/md_cg/test_issue52_scan_condition_first.py +1 -1
- package/md_cg/test_lifecycle_retire_leak.py +408 -0
- package/md_cg/test_lock.py +16 -7
- package/md_cg/test_m3_h9_semantic_guard.py +1 -1
- package/md_cg/test_n230_dirty_replay.py +375 -375
- package/md_cg/test_n238_body_text_parity.py +156 -0
- package/md_cg/test_n276_probe_hoist.py +199 -0
- package/md_cg/test_p4_freshness.py +95 -1
- package/md_cg/test_policy_required_ccg.py +3 -1
- package/md_cg/test_read_face_semantics.py +6 -3
- package/md_cg/test_readcache_prodpath.py +66 -0
- package/md_cg/test_sleep.py +58 -1
- package/md_cg/test_sleep_p1.py +218 -2
- package/md_cg/test_state_event_op.py +514 -0
- package/md_cg/test_state_events.py +178 -0
- package/md_cg/test_state_slots.py +691 -0
- package/md_cg/test_time_core_lint.py +8 -1
- package/md_cg/test_writepipe.py +8 -5
- package/md_cg/tokens.py +18 -2
- package/md_cg/writepipe.py +76 -0
- package/package.json +2 -2
- package/skills/plugin.json +1 -1
- package/src/bridge.ts +9 -0
- package/src/hooks.ts +599 -517
- package/src/lib/hook_audit.ts +243 -0
- package/src/lib/mutual.ts +5 -1
- package/src/lib/roleplay_web.ts +17 -2
- package/src/lib/session_state.ts +127 -0
- package/src/tools.ts +12 -1
- package/zcode/AGENTS.md +6 -6
package/md_cg/test_sleep_p1.py
CHANGED
|
@@ -34,6 +34,14 @@
|
|
|
34
34
|
G7 冲突挂起——主库/影子同 id 并发改动 ⇒ 该 id 进 `conflicts`、**未写进主库**、
|
|
35
35
|
也未进影子分支的树;另一条(未冲突的)正常合并。
|
|
36
36
|
G8 回滚——对合并提交 `revert`:主库真源面回到合并前,历史不丢(只增不减)。
|
|
37
|
+
G9 物化窗口内漂移(issue #60)——`ok` 与 `face_stable` 拆开后,活跃工作区
|
|
38
|
+
(每轮都有真源面改动)**照常迭代**:phases 含 iterate、②③④ 不再记
|
|
39
|
+
「本轮未迭代」、台账落一条含 iterate 的记录。
|
|
40
|
+
G10 手动入口(issue #61)——`--once` 不等 tick 即落台账并打印与台账同源的
|
|
41
|
+
「本轮未迭代原因」;`--once --dry-run` 只预览(零台账新增、零物化);
|
|
42
|
+
`--dry-run` 单独使用报错;`--status` 带 `last_cycle` 段。
|
|
43
|
+
G11 物化未完成(父进程持根级锁 ⇒ busy)——②③④ 记「物化未完成:…」,
|
|
44
|
+
与门拦 gate_reason **可区分**(`rec["skipped"]` 为空、两处文案同源)。
|
|
37
45
|
|
|
38
46
|
运行:python -X utf8 -m md_cg.test_sleep_p1
|
|
39
47
|
python -X utf8 -m md_cg.test_sleep_p1 --mutate # 定点变异自证
|
|
@@ -59,6 +67,7 @@ import types
|
|
|
59
67
|
|
|
60
68
|
from . import sleep as SL
|
|
61
69
|
from . import sustain as SUS
|
|
70
|
+
from .fsutil import FileLock
|
|
62
71
|
|
|
63
72
|
_PASS = []
|
|
64
73
|
_FAIL = []
|
|
@@ -611,7 +620,203 @@ def g8_revert():
|
|
|
611
620
|
"G8e 历史只增不减(revert 自身也进历史)")
|
|
612
621
|
|
|
613
622
|
|
|
614
|
-
|
|
623
|
+
# ---------------------------------------------------------------- G9
|
|
624
|
+
class _Cap(io.StringIO):
|
|
625
|
+
"""捕获 `_main` 的输出——它开头会调 `sys.stdout.reconfigure`,纯 StringIO
|
|
626
|
+
没有这个方法(真 stdout 才有),故补一个空实现。"""
|
|
627
|
+
|
|
628
|
+
def reconfigure(self, **_kw): # noqa: D102 —— 空实现
|
|
629
|
+
pass
|
|
630
|
+
|
|
631
|
+
|
|
632
|
+
def _drift_probe(S, *, at=2, rel="knowledge/n_drift.md"):
|
|
633
|
+
"""物化窗口内漂移模拟(补丁就地装上):第 `at` 次调用 `source_face_hashes` 时
|
|
634
|
+
多返回一条新增路径(其余调用照真源);返回**还原函数**。
|
|
635
|
+
|
|
636
|
+
补丁打在**函数实际读取的命名空间**上(`materialize.__globals__`)而不是模块
|
|
637
|
+
属性:变异自证时 `SL` 是 exec 出来的模块,其函数读 exec 命名空间,而模块对象
|
|
638
|
+
的 `__dict__` 只是它的副本——打在模块属性上,变异后的模块内部调用看不到补丁
|
|
639
|
+
(本机实测:G9 会在变异下空转)。真源码下两者是同一个 dict。
|
|
640
|
+
"""
|
|
641
|
+
ns = S.materialize.__globals__
|
|
642
|
+
real = ns["source_face_hashes"]
|
|
643
|
+
seen = {"n": 0}
|
|
644
|
+
|
|
645
|
+
def _wrap(r):
|
|
646
|
+
seen["n"] += 1
|
|
647
|
+
d = dict(real(r))
|
|
648
|
+
if seen["n"] == at:
|
|
649
|
+
d[rel] = "0" * 64
|
|
650
|
+
return d
|
|
651
|
+
|
|
652
|
+
ns["source_face_hashes"] = _wrap
|
|
653
|
+
|
|
654
|
+
def _restore():
|
|
655
|
+
ns["source_face_hashes"] = real
|
|
656
|
+
|
|
657
|
+
return _restore
|
|
658
|
+
|
|
659
|
+
|
|
660
|
+
def g9():
|
|
661
|
+
print("== G9 物化窗口内漂移 ⇒ 照常迭代(#60:不再自我否决)==")
|
|
662
|
+
S = globals()["SL"]
|
|
663
|
+
gen, root, state = _fixture(contextual_hot=1, unverified=1)
|
|
664
|
+
from .mdcos import MdCGOS
|
|
665
|
+
cg = MdCGOS(root)
|
|
666
|
+
n0 = len(S.read_ledger())
|
|
667
|
+
restore = _drift_probe(S)
|
|
668
|
+
try:
|
|
669
|
+
r = S.run_cycle(cg, batch="G9B1", round_index=1, now="03:00")
|
|
670
|
+
finally:
|
|
671
|
+
restore()
|
|
672
|
+
ph = r["steps"][6]["phases"]
|
|
673
|
+
mat = ph.get("materialize") or {}
|
|
674
|
+
ok(mat.get("ok") is True and mat.get("face_stable") is False,
|
|
675
|
+
"G9a 漂移窗口内物化仍记 ok=True、face_stable=False", mat)
|
|
676
|
+
ok(bool(ph.get("iterate")),
|
|
677
|
+
"G9b **物化成功即迭代**:phases 含 iterate 读数(非 None)", sorted(ph))
|
|
678
|
+
ok(all(not s.get("skipped") for s in r["steps"][1:4]),
|
|
679
|
+
"G9c 九步 ②③④ 不再是「本轮未迭代」(裁在门拦或物化未完成,二者皆非)",
|
|
680
|
+
[s.get("skipped") for s in r["steps"][1:4]])
|
|
681
|
+
ok(len(S.read_ledger()) == n0 + 1, "G9d 本轮记账(台账 +1)",
|
|
682
|
+
(n0, len(S.read_ledger())))
|
|
683
|
+
led = S.read_ledger()[-1]
|
|
684
|
+
ok(led.get("batch") == "G9B1"
|
|
685
|
+
and "iterate" in ((led.get("steps") or [{}] * 7)[6].get("phases") or {}),
|
|
686
|
+
"G9e 台账落一条**含 iterate** 的记录(可回看「上次为何迭代/未迭代」)",
|
|
687
|
+
(led.get("batch"), sorted((((led.get("steps") or [{}] * 7)[6]
|
|
688
|
+
.get("phases") or {})))))
|
|
689
|
+
|
|
690
|
+
|
|
691
|
+
# ---------------------------------------------------------------- G10
|
|
692
|
+
def g10():
|
|
693
|
+
print("== G10 手动入口:--once / --once --dry-run / --status(#61 不等 tick)==")
|
|
694
|
+
S = globals()["SL"]
|
|
695
|
+
import time as _t
|
|
696
|
+
gen, root, state = _fixture(contextual_hot=1, unverified=1)
|
|
697
|
+
lt = _t.localtime()
|
|
698
|
+
cur = lt.tm_hour * 60 + lt.tm_min
|
|
699
|
+
a0, b0 = (cur + 120) % 1440, (cur + 180) % 1440
|
|
700
|
+
win = "%02d:%02d-%02d:%02d" % (a0 // 60, a0 % 60, b0 // 60, b0 % 60)
|
|
701
|
+
ok(S.in_window(win, None) is False,
|
|
702
|
+
"G10 前置:构造出的窗口确定性地不含当前时刻(%s)" % win)
|
|
703
|
+
# ① --once --dry-run(窗口内):零台账新增、零物化,打印「将执行…」
|
|
704
|
+
os.environ["MDCG_SLEEP_WINDOW"] = ""
|
|
705
|
+
n0 = len(S.read_ledger())
|
|
706
|
+
cap = _Cap()
|
|
707
|
+
with contextlib.redirect_stdout(cap):
|
|
708
|
+
rc = S._main(["--root", root, "--once", "--dry-run"])
|
|
709
|
+
txt = cap.getvalue()
|
|
710
|
+
ok(rc == 0 and len(S.read_ledger()) == n0,
|
|
711
|
+
"G10a --once --dry-run **零台账新增**", (rc, n0, len(S.read_ledger())))
|
|
712
|
+
ok("将执行物化→迭代→对账→合并" in txt,
|
|
713
|
+
"G10b 预览打印「将执行物化→迭代→对账→合并」",
|
|
714
|
+
[l for l in txt.splitlines() if l.startswith("预览")])
|
|
715
|
+
ok(not os.path.isdir(os.path.join(state, "sleep", "shadow"))
|
|
716
|
+
and not os.path.isdir(os.path.join(state, "sleep", "lib.git")),
|
|
717
|
+
"G10c dry-run **不物化**(影子与版本库都没建出来)")
|
|
718
|
+
# ② --dry-run 单独使用 → 报错
|
|
719
|
+
cap2, err2 = _Cap(), io.StringIO()
|
|
720
|
+
with contextlib.redirect_stdout(cap2), contextlib.redirect_stderr(err2):
|
|
721
|
+
rc2 = S._main(["--root", root, "--dry-run"])
|
|
722
|
+
ok(rc2 == 2 and "--dry-run" in err2.getvalue(),
|
|
723
|
+
"G10d --dry-run 单独使用给出报错(返回 2,不执行任何动作)",
|
|
724
|
+
(rc2, err2.getvalue().strip()))
|
|
725
|
+
# ③ --once(窗口外,确定性构造):落台账 + 打印与台账同源的原因
|
|
726
|
+
os.environ["MDCG_SLEEP_WINDOW"] = win
|
|
727
|
+
n1 = len(S.read_ledger())
|
|
728
|
+
cap3 = _Cap()
|
|
729
|
+
with contextlib.redirect_stdout(cap3):
|
|
730
|
+
rc3 = S._main(["--root", root, "--once"])
|
|
731
|
+
txt3 = cap3.getvalue()
|
|
732
|
+
led = S.read_ledger()
|
|
733
|
+
ok(rc3 == 0 and len(led) == n1 + 1 and len(led) > n0,
|
|
734
|
+
"G10e --once 不等 tick 即落一条台账记录", (rc3, n1, len(led)))
|
|
735
|
+
rec = led[-1]
|
|
736
|
+
ok("窗口外" in (rec.get("skipped") or ""),
|
|
737
|
+
"G10e2 台账记门拦原因(窗口外)", rec.get("skipped"))
|
|
738
|
+
ok("本轮未迭代原因:" in txt3 and (rec.get("skipped") or "") in txt3,
|
|
739
|
+
"G10e3 --once 显式打印「本轮未迭代原因」,文案与台账同源",
|
|
740
|
+
[l for l in txt3.splitlines() if l.startswith("本轮未迭代原因")])
|
|
741
|
+
ok(all(s.get("skipped") == rec.get("skipped") for s in rec["steps"][1:4]),
|
|
742
|
+
"G10e4 台账 ②③④ 的 skip 文案 == 同一门拦原因(不静默)",
|
|
743
|
+
[s.get("skipped") for s in rec["steps"][1:4]])
|
|
744
|
+
# ④ --status:last_cycle = 最近一条台账记录
|
|
745
|
+
def _status():
|
|
746
|
+
capx = _Cap()
|
|
747
|
+
with contextlib.redirect_stdout(capx):
|
|
748
|
+
rcx = S._main(["--root", root, "--status"])
|
|
749
|
+
return rcx, json.loads(capx.getvalue())
|
|
750
|
+
|
|
751
|
+
rcx, doc = _status()
|
|
752
|
+
lc = doc.get("last_cycle") or {}
|
|
753
|
+
ok(rcx == 0 and lc.get("batch") == rec.get("batch")
|
|
754
|
+
and lc.get("round") == rec.get("round")
|
|
755
|
+
and lc.get("candidates") == rec.get("candidates")
|
|
756
|
+
and lc.get("skipped") == rec.get("skipped"),
|
|
757
|
+
"G10f --status 的 last_cycle = 最近一条台账记录(t/batch/round/"
|
|
758
|
+
"candidates/skipped)", lc)
|
|
759
|
+
ok(lc.get("not_iterated_reason") == rec.get("skipped")
|
|
760
|
+
and "窗口外" in (lc.get("not_iterated_reason") or ""),
|
|
761
|
+
"G10f2 last_cycle 带「上次为何没迭代」的一致原因",
|
|
762
|
+
lc.get("not_iterated_reason"))
|
|
763
|
+
ok(lc.get("steps_skip") == {s.get("step"): s.get("skipped")
|
|
764
|
+
for s in rec["steps"][1:4]},
|
|
765
|
+
"G10f3 last_cycle 带 ②③④ 的 skip 文案", lc.get("steps_skip"))
|
|
766
|
+
# ⑤ --once(窗口内):真跑一轮(物化→迭代→对账→合并)后再看 --status
|
|
767
|
+
os.environ["MDCG_SLEEP_WINDOW"] = ""
|
|
768
|
+
cap4 = _Cap()
|
|
769
|
+
with contextlib.redirect_stdout(cap4):
|
|
770
|
+
rc4 = S._main(["--root", root, "--once"])
|
|
771
|
+
rec4 = S.read_ledger()[-1]
|
|
772
|
+
ok(rc4 == 0 and rec4.get("skipped") is None
|
|
773
|
+
and (rec4.get("candidates") or 0) > 0,
|
|
774
|
+
"G10g 窗口内 --once 真迭代(非只记账)",
|
|
775
|
+
{k: rec4.get(k) for k in ("skipped", "candidates", "merged")})
|
|
776
|
+
rcx2, doc2 = _status()
|
|
777
|
+
lc2 = doc2.get("last_cycle") or {}
|
|
778
|
+
mz = lc2.get("materialize") or {}
|
|
779
|
+
ok(isinstance(mz, dict) and all(k in mz for k in ("ok", "busy", "face_stable"))
|
|
780
|
+
and mz.get("ok") is True and mz.get("busy") is False
|
|
781
|
+
and mz.get("face_stable") is True,
|
|
782
|
+
"G10h last_cycle 带 phases.materialize 摘要(ok/busy/face_stable)", mz)
|
|
783
|
+
ok(lc2.get("not_iterated_reason") is None,
|
|
784
|
+
"G10h2 迭代过的一轮不报「未迭代原因」", lc2.get("not_iterated_reason"))
|
|
785
|
+
os.environ.pop("MDCG_SLEEP_WINDOW", None)
|
|
786
|
+
|
|
787
|
+
|
|
788
|
+
# ---------------------------------------------------------------- G11
|
|
789
|
+
def g11():
|
|
790
|
+
print("== G11 物化未完成(根级锁被占)⇒ ②③④ 记**可区分**的 skip 文案 ==")
|
|
791
|
+
S = globals()["SL"]
|
|
792
|
+
gen, root, state = _fixture(contextual_hot=1, unverified=1)
|
|
793
|
+
from .mdcos import MdCGOS
|
|
794
|
+
cg = MdCGOS(root)
|
|
795
|
+
lp = S.lock_path()
|
|
796
|
+
with FileLock(lp, timeout=5.0, strict=False) as lk:
|
|
797
|
+
ok(lk.acquired is True, "G11 前置:父进程已持根级锁", lp)
|
|
798
|
+
r = S.run_cycle(cg, batch="G11B1", round_index=1, now="03:00",
|
|
799
|
+
timeout=0.3)
|
|
800
|
+
ph = r["steps"][6]["phases"].get("materialize") or {}
|
|
801
|
+
ok(ph.get("ok") is False and ph.get("busy") is True,
|
|
802
|
+
"G11a 取不到根级锁 ⇒ 物化 ok=False、busy=True(早退路径语义不变)", ph)
|
|
803
|
+
texts = [s.get("skipped") for s in r["steps"][1:4]]
|
|
804
|
+
ok(all(t and t.startswith("物化未完成:") for t in texts),
|
|
805
|
+
"G11b ②③④ 记「物化未完成:…」——与门拦 gate_reason **可区分**", texts)
|
|
806
|
+
ok(r.get("skipped") is None,
|
|
807
|
+
"G11c 四道门全过 ⇒ rec['skipped'] 为空:两类未迭代原因不混同",
|
|
808
|
+
r.get("skipped"))
|
|
809
|
+
ok(S.cycle_not_iterated_reason(r) == texts[0],
|
|
810
|
+
"G11d 「本轮未迭代原因」== 台账 ②③④ 的同一文案(CLI 与台账同源)",
|
|
811
|
+
S.cycle_not_iterated_reason(r))
|
|
812
|
+
led = S.read_ledger()[-1]
|
|
813
|
+
ok(led.get("batch") == "G11B1"
|
|
814
|
+
and all((s.get("skipped") or "").startswith("物化未完成:")
|
|
815
|
+
for s in led["steps"][1:4]),
|
|
816
|
+
"G11e 物化未完成的一轮同样落台账(可回看)", led.get("batch"))
|
|
817
|
+
|
|
818
|
+
|
|
819
|
+
_GROUPS = (g0, g8, g1, g2, g3, g4, g5, g6, g7, g8_revert, g9, g10, g11)
|
|
615
820
|
|
|
616
821
|
|
|
617
822
|
def _run_groups() -> int:
|
|
@@ -639,8 +844,14 @@ _MUTATIONS = (
|
|
|
639
844
|
("窗口跨午夜判据写反", "md_cg/sleep.py",
|
|
640
845
|
" return t >= start or t < end",
|
|
641
846
|
" return t >= start and t < end"),
|
|
847
|
+
# 锚点同步(2026-10-06):本条此前锚在裁定⑰之前的旧 parse_window 形态上,实现
|
|
848
|
+
# 改了而表未同步 ⇒ `--mutate` 恒以 ANCHOR-MISS 退出 2(**先存**缺陷,非本批引入;
|
|
849
|
+
# 判据 scripts/run_tests.py 不跑 --mutate,故一直未被门禁兜住)。此处按当前实现
|
|
850
|
+
# 重新锚定**同一意图**的变异(留空/非法不再当作全时段,回落 (0,1) 窄窗)——不放宽
|
|
851
|
+
# 也不删除任何既有断言。实测红集 7 项 = G1f/G1h/G1h3 + 依赖空窗全时段入口的新
|
|
852
|
+
# 断言组 G10b/G10g/G10h(编排侧 --mutate 亲跑读数)。
|
|
642
853
|
("留空/非法窗口不再视作全时段", "md_cg/sleep.py",
|
|
643
|
-
" s = str(spec or \"\").strip()\n if not s
|
|
854
|
+
" s = str(spec or \"\").strip()\n if not s:\n return None # 留空 = 全时段(唯一显式入口)",
|
|
644
855
|
" s = str(spec or \"\").strip()\n if not s or \"-\" not in s:\n return (0, 1)"),
|
|
645
856
|
("密文项不再被闸拦下(会随分支入册)", "md_cg/sleep.py",
|
|
646
857
|
' "reason": ("影子侧为密文节点(无密钥不重放、"\n'
|
|
@@ -676,6 +887,11 @@ _MUTATIONS = (
|
|
|
676
887
|
" pass # 睡眠周期失败不中断常驻\n"
|
|
677
888
|
" next_sleep = now + self.sleep_interval\n",
|
|
678
889
|
""),
|
|
890
|
+
# issue #60:物化 ok 语义回退成旧「真源面未变才算成功」——活跃工作区(每轮
|
|
891
|
+
# 都有真源面改动)将永不自迭代;预期红集 = 断言组 G9(G9b/G9c/G9e)。
|
|
892
|
+
("物化 ok 语义回退(漂移即不迭代)", "md_cg/sleep.py",
|
|
893
|
+
' if m.get("ok"):\n # **物化成功即迭代**(issue #60)',
|
|
894
|
+
' if m.get("ok") and m.get("face_stable"):\n # **物化成功即迭代**(issue #60)'),
|
|
679
895
|
("两入口不再共用 sleep 读取器(写死 auto)", "md_cg/mcp_server.py",
|
|
680
896
|
" sleep_interval=_sleep.sleep_interval(),\n"
|
|
681
897
|
" auto_sleep=_sleep.sleep_enabled(),\n"
|