@furongjun1999/dsh-memory 0.6.0 → 0.7.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 +618 -572
- package/codebuddy/CODEBUDDY.md +10 -10
- package/data/policy.json +27 -0
- package/docs/README.md +1 -0
- package/docs/discipline/harnesses.yaml +31 -0
- package/docs/discipline/templates/full.md.tmpl +1 -1
- package/docs/discipline/templates/rules.mdc.tmpl +1 -1
- 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 +418 -0
- 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 +441 -0
- 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 +398 -0
- 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 +498 -0
- 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 +669 -0
- 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 +683 -0
- 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 +460 -0
- 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 +205 -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 +97 -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 +458 -0
- package/docs/eval//346/200/247/350/203/275/344/270/223/351/241/271_/345/206/267/346/237/245/350/257/242/344/270/216/345/206/205/345/255/230_v1.0.md +218 -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 +10 -0
- 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 +646 -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_v20.md +283 -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_v21.md +224 -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_v22.md +223 -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_v23.md +293 -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_v24.md +303 -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_v25.md +230 -0
- package/docs/hive//346/243/200/347/264/242/347/256/227/346/263/225/345/217/243/345/276/204/345/257/271/347/205/247_v0.1.md +136 -11
- package/docs/hive//346/243/200/347/264/242/350/267/257/345/276/204/344/270/216/350/256/244/347/237/245/347/273/223/346/236/204/345/245/221/347/272/246_v0.1.md +52 -2
- 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/mdcg/README/350/257/246/347/273/206/347/211/210_v0.4.10.md +100 -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/mdcg//345/217/221/345/270/203/351/227/250/347/246/201/351/223/276_v0.1.md +57 -9
- package/docs/mdcg//347/201/265/346/236/242/350/256/260/345/277/206/345/212/250/350/257/215/345/215/217/350/256/256_v1.0-draft.md +7 -2
- 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 +183 -0
- package/docs/mdcg//350/256/244/347/237/245/345/233/276_/347/264/242/345/274/225/344/270/216/345/267/245/347/250/213/350/247/204/350/214/203/345/214/226_/350/256/241/345/210/222_v0.1.md +39 -3
- 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 +220 -0
- package/docs/plans//347/234/237/346/272/220/347/264/242/345/274/225_/351/200/232/347/224/250/346/234/272/345/210/266_v0.3.md +227 -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 +547 -0
- package/docs/plans//350/234/202/345/267/242/346/250/241/345/236/213/345/257/206/351/222/245/351/205/215/347/275/256/351/235/242_v1.0.md +385 -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 +460 -460
- package/lib/bridge.js +24 -2
- package/lib/hooks.d.ts +31 -2
- package/lib/hooks.js +219 -16
- package/lib/init.js +16 -1
- package/lib/lib/prompt_safety.d.ts +52 -1
- package/lib/lib/prompt_safety.js +76 -1
- package/md_cg/audit.py +652 -379
- package/md_cg/bench6_arms.py +1 -1
- package/md_cg/bench_e2e_locomo_qa.py +11 -4
- package/md_cg/bench_p0.py +1 -1
- package/md_cg/branches.py +2 -2
- package/md_cg/ccgc.py +1071 -1006
- package/md_cg/chain.py +48 -1
- package/md_cg/consistency.py +97 -9
- package/md_cg/consolidate.py +34 -9
- package/md_cg/crypto.py +59 -26
- package/md_cg/docindex.py +16 -1
- package/md_cg/evolution.py +17 -1
- package/md_cg/export.py +1 -1
- package/md_cg/forgetting.py +309 -13
- package/md_cg/freshness.py +511 -0
- package/md_cg/fsutil.py +454 -8
- package/md_cg/generation.py +409 -0
- package/md_cg/hotcache.py +4 -1
- package/md_cg/identity.py +3 -3
- package/md_cg/insight.py +24 -3
- package/md_cg/linkref.py +1 -1
- package/md_cg/logref.py +327 -0
- package/md_cg/mcp_server.py +4261 -3818
- package/md_cg/mdcg.py +4695 -3547
- package/md_cg/mdcos.py +4672 -4159
- package/md_cg/mreview/pipeline.py +15 -1
- package/md_cg/nodefile.py +713 -576
- package/md_cg/protect.py +158 -11
- package/md_cg/protocol.py +41 -2
- package/md_cg/provenance.py +22 -4
- package/md_cg/reach.py +4 -4
- package/md_cg/readcache.py +76 -15
- package/md_cg/reconcile.py +1 -1
- package/md_cg/refindex.py +246 -37
- package/md_cg/refine.py +1 -1
- package/md_cg/routing.py +32 -5
- package/md_cg/run_tests.py +17 -0
- package/md_cg/scrub.py +30 -3
- package/md_cg/security.py +47 -1
- package/md_cg/self_state.py +5 -5
- package/md_cg/semantic/canonical.py +22 -0
- package/md_cg/semantic/unify.py +73 -22
- package/md_cg/semantic/unify_fixture.json +25 -0
- package/md_cg/sleep.py +1297 -0
- package/md_cg/sources.py +23 -6
- package/md_cg/srcindex.py +352 -0
- package/md_cg/stg.py +47 -3
- package/md_cg/subgraph.py +2 -2
- package/md_cg/sustain.py +1436 -1168
- package/md_cg/tasks.py +469 -470
- package/md_cg/test_auto_defaults.py +424 -0
- package/md_cg/test_b1_auto_id_multiproc.py +277 -0
- package/md_cg/test_b1b2_write_face.py +417 -0
- package/md_cg/test_b2_sensitivity_landing.py +223 -0
- package/md_cg/test_b3_merge_keeps_content.py +576 -0
- package/md_cg/test_b4_shard_dir_selfheal.py +843 -0
- package/md_cg/test_b4_shard_dir_selfheal_guard.py +238 -0
- package/md_cg/test_boundary_hit.py +410 -0
- package/md_cg/test_c3_transient_read_negative.py +793 -0
- package/md_cg/test_c8_search_rrf_gates.py +502 -0
- package/md_cg/test_ccg_form_parity.py +188 -0
- package/md_cg/test_ccgc.py +28 -3
- package/md_cg/test_en_pipeline.py +22 -13
- package/md_cg/test_generation_guard.py +352 -0
- package/md_cg/test_govern_directread.py +17 -4
- package/md_cg/test_h2_session_view_norm.py +233 -0
- package/md_cg/test_h4_sustain_snapshot.py +1387 -0
- package/md_cg/test_hive_ingest.py +285 -285
- package/md_cg/test_issue39_utf8_stdio.py +307 -16
- package/md_cg/test_issue43_default_policy.py +865 -0
- package/md_cg/test_legacy_p3_node_id_type.py +375 -0
- package/md_cg/test_linkref.py +10 -3
- package/md_cg/test_lock.py +2 -2
- package/md_cg/test_logref.py +1109 -0
- package/md_cg/test_m3_h9_bucket_health_protect_mark.py +301 -0
- package/md_cg/test_m3_h9_semantic_guard.py +525 -0
- package/md_cg/test_mr_m2.py +15 -3
- package/md_cg/test_n130_verify_falsified_protect.py +1 -1
- package/md_cg/test_n139_dek_provision_failclosed.py +185 -0
- package/md_cg/test_n176_link_trust.py +221 -0
- package/md_cg/test_n178_units_jobid_gate.py +212 -0
- package/md_cg/test_n184_keys_concurrent_provision.py +307 -0
- package/md_cg/test_n195_writepath_reload.py +283 -0
- package/md_cg/test_n196_stale_gate_skip.py +169 -0
- package/md_cg/test_n197_n208_write_face_gates.py +471 -0
- package/md_cg/test_n198_tokens_corrupt_failclosed.py +225 -0
- package/md_cg/test_n199_tokens_concurrent_write.py +378 -0
- package/md_cg/test_n201_proposal_visibility.py +382 -0
- package/md_cg/test_n202_session_notes_visibility.py +461 -0
- package/md_cg/test_n204_n205_n226_n227_n228_n229_exit_gates.py +542 -0
- package/md_cg/test_n206_stdio_jsonrpc_type.py +403 -0
- package/md_cg/test_n209_verify_write_face_gates.py +461 -0
- package/md_cg/test_n212_n213_n224_generation_gates.py +519 -0
- package/md_cg/test_n214_n215_n221_n222_write_face_gates.py +563 -0
- package/md_cg/test_n225_nonobject_load.py +1110 -0
- package/md_cg/test_n230_dirty_replay.py +375 -0
- package/md_cg/test_n62_tenant_bind_failclosed.py +200 -0
- package/md_cg/test_neg_condition_hits.py +333 -0
- package/md_cg/test_neg_tail_honesty.py +663 -0
- package/md_cg/test_none_id_write_guard.py +4 -3
- package/md_cg/test_opt_batch1_md_cg.py +451 -0
- package/md_cg/test_p1.py +5 -5
- package/md_cg/test_p11_consistency.py +161 -12
- package/md_cg/test_p26_refindex.py +2 -2
- package/md_cg/test_p27_docindex.py +777 -774
- package/md_cg/test_p28_refcheck.py +740 -13
- package/md_cg/test_p29_session_ingest_export.py +2 -2
- package/md_cg/test_p2_mcp.py +12 -1
- package/md_cg/test_p2_six_elements.py +463 -0
- package/md_cg/test_p30_maintain.py +33 -2
- package/md_cg/test_p31_insight.py +1 -0
- package/md_cg/test_p3_legacy_closure.py +433 -0
- package/md_cg/test_p4_freshness.py +680 -0
- package/md_cg/test_p8_subgraph_chain.py +14 -1
- package/md_cg/test_p9c_dedup_hints.py +276 -0
- package/md_cg/test_policy_required_ccg.py +426 -0
- package/md_cg/test_protocol.py +22 -0
- package/md_cg/test_rank_parity_score_mode.py +522 -0
- package/md_cg/test_read_face_input_gates.py +363 -0
- package/md_cg/test_read_face_semantics.py +489 -0
- package/md_cg/test_recall_face_guards.py +812 -0
- package/md_cg/test_rejected_credential_forms.py +188 -0
- package/md_cg/test_rejected_redact.py +146 -0
- package/md_cg/test_retr_s1b.py +2 -2
- package/md_cg/test_retr_s5.py +20 -7
- package/md_cg/test_review_conformance.py +21 -3
- package/md_cg/test_security_audit_v21.py +2 -2
- package/md_cg/test_semantic_canonical.py +5 -3
- package/md_cg/test_server_version.py +67 -0
- package/md_cg/test_sleep.py +611 -0
- package/md_cg/test_sleep_p1.py +784 -0
- package/md_cg/test_srcindex.py +171 -0
- package/md_cg/test_tenant_env_override_warn.py +63 -50
- package/md_cg/test_time_core_lint.py +968 -0
- package/md_cg/test_token_lowercase_form.py +315 -0
- package/md_cg/test_unify_default_off.py +701 -0
- package/md_cg/test_unify_scope.py +182 -0
- package/md_cg/test_v21r1_package_version.py +310 -0
- package/md_cg/test_writepipe.py +10 -4
- package/md_cg/tokens.py +225 -95
- package/md_cg/tool_face.py +4 -4
- package/md_cg/trust.py +49 -5
- package/md_cg/units.py +204 -6
- package/md_cg/weights.py +4 -4
- package/md_cg/whitebox_kb/aeis_core/time_core.py +8 -0
- package/md_cg/whitebox_kb/wisdom/knowledge_points.py +1 -1
- package/md_cg/writelimit.py +42 -8
- package/md_cg/writepipe.py +651 -554
- package/package.json +4 -2
- package/skills/plugin.json +1 -1
- package/src/bridge.ts +25 -2
- package/src/hooks.ts +229 -16
- package/src/init.ts +15 -1
- package/src/lib/prompt_safety.ts +88 -1
- package/utf8_boot.py +237 -0
- package/zcode/AGENTS.md +10 -10
package/utf8_boot.py
ADDED
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""utf8_boot.py · 入口自保证 UTF-8(进程自保证,不依赖使用者 profile 的环境变量)。
|
|
3
|
+
|
|
4
|
+
为什么放在**仓库根**、而不是 `md_cg/` 里
|
|
5
|
+
------------------------------------------------------------------------
|
|
6
|
+
本模块被 hive / md_cg / scripts 三处的**进程入口**共用。放进 `md_cg/` 会让
|
|
7
|
+
`import md_cg` 拉起整个认知图包(`md_cg/__init__.py` 会 `import .mdcg`)——为一次
|
|
8
|
+
UTF-8 检查付出「重包导入的启动成本 + hive/scripts 入口被绑上 md_cg 依赖方向」的
|
|
9
|
+
双重代价。放仓库根 = 零第三方、零 md_cg 依赖、入口一行 `sys.path` 插入即可用。
|
|
10
|
+
|
|
11
|
+
它解决什么(修前事实,本机 2026-09-29 实测)
|
|
12
|
+
------------------------------------------------------------------------
|
|
13
|
+
* `locale.getlocale()` = `('Chinese (Simplified)_China', '936')`,
|
|
14
|
+
`locale.getpreferredencoding(False)` = `cp936`;Python 裸 `open()` 的缺省编码
|
|
15
|
+
与 stdio 的控制台代码页都跟着 locale 走。
|
|
16
|
+
* 清空 `PYTHONUTF8` / `PYTHONIOENCODING` 后实测:裸 `open()` 读 UTF-8 中文文件抛
|
|
17
|
+
`UnicodeDecodeError`;`sys.stdout.write("中文")` 静默产出 GBK 字节(`\\xd6\\xd0\\xce\\xc4`);
|
|
18
|
+
裸 `open(p, "w")` 写中文落 GBK 字节——**静默坏**,比抛异常更难查。
|
|
19
|
+
* 本机之所以没炸,是因为**环境里**有 `PYTHONUTF8=1` + `PYTHONIOENCODING=utf-8`,
|
|
20
|
+
且部分入口自己钉(`scripts/run_tests.py` 给子进程覆盖、`scripts/linux_verify.sh`
|
|
21
|
+
export、`src/lib/mdcg_client.ts` 设 PYTHONUTF8)。
|
|
22
|
+
⇒ 正确性挂在「环境变量 + 每个入口记得设」上:换台没设的机器,或新入口漏设,
|
|
23
|
+
即走 GBK。本模块把该保证**下沉到进程自身**。
|
|
24
|
+
|
|
25
|
+
三条路(`ensure_utf8` 的分支)
|
|
26
|
+
------------------------------------------------------------------------
|
|
27
|
+
0. **调用方不是进程入口(被 import)→ 只置 env 即返回**——绝不重启、绝不退出、绝不打
|
|
28
|
+
日志。见下「被 import 时不得重启(F6)」。
|
|
29
|
+
1. `sys.flags.utf8_mode` 为真 → 立即返回(不重启、不打日志);
|
|
30
|
+
2. 为假 → **默认重启自身**(`-X utf8`);重启后子进程 `utf8_mode` 已开 ⇒ 结构上
|
|
31
|
+
不可能二次重启(幂等,见守卫的「只重启一次」判据);
|
|
32
|
+
3. 显式退出通道:env `LINGSHU_UTF8_NO_REEXEC` 为真 → **fail-fast** 非 0 退出并打印
|
|
33
|
+
可执行指引(不能接受子进程的场景:嵌入式宿主、CI 调试、进程树审计)。
|
|
34
|
+
|
|
35
|
+
无论走哪条路(含第 0 路),都会把 `PYTHONUTF8=1` 与 `PYTHONIOENCODING=utf-8` 置入
|
|
36
|
+
`os.environ`,供本进程随后派生的子进程继承(执行器/编排器派生子进程时的第二道保险)。
|
|
37
|
+
|
|
38
|
+
被 import 时不得重启(F6,2026-09-29 复核实测)
|
|
39
|
+
------------------------------------------------------------------------
|
|
40
|
+
本助手在七个入口里都是**模块级**调用,而其中数个入口**同时是被 import 的库**
|
|
41
|
+
(`hive/serve_start.py` 被 `hive/hive_mcp/mcp_server.py` 导入、`hive/exec.py` 被
|
|
42
|
+
`hive/orch.py` 导入)。若「被 import」也整进程重启:调用方正在处理的输入会被吞掉。
|
|
43
|
+
复核员构造态实测(未加本判据前):单会话解释器启动 2 次、第 3 条请求被吞、
|
|
44
|
+
**无错误帧、rc=0**——静默坏,比抛异常更难查。故重启/fail-fast 只在
|
|
45
|
+
「调用方模块 == `__main__`」时发生;被 import 时只置 env。
|
|
46
|
+
|
|
47
|
+
fail-fast 指引必须**可照抄**(F2,2026-09-29 复核实测)
|
|
48
|
+
------------------------------------------------------------------------
|
|
49
|
+
指引此前一律印 `python -X utf8 <入口 __file__>`;而两个 MCP 入口的真实接入形态是
|
|
50
|
+
`python -m md_cg.mcp_server` / `python -m hive.hive_mcp.mcp_server`(mcp.json 直连),
|
|
51
|
+
照抄文件形态会 `ImportError: attempted relative import with no known parent package`
|
|
52
|
+
(实测 rc=1)。故 `_guidance` 复用与 `reexec_argv()` **同一**判别(`__main__.__spec__`
|
|
53
|
+
有 name 与 parent ⇒ `-m` 形态),印 `python -X utf8 -m <模块名>`。
|
|
54
|
+
|
|
55
|
+
**禁用 `os.exec*` 系列**:Windows 上进程替换与标准句柄继承的语义不可靠,而 MCP 是
|
|
56
|
+
**字节组帧**的 stdio 协议——重启必须显式传递 `stdin`/`stdout`/`stderr` 三个标准流,
|
|
57
|
+
丢了组帧就是灾难。故本模块只用 `subprocess.run`(实测:父进程退出后子进程持有的
|
|
58
|
+
管道句柄仍完好)。
|
|
59
|
+
|
|
60
|
+
与设计裁决的一处偏离(已在回报中声明,理由是端到端组帧这条真判据)
|
|
61
|
+
------------------------------------------------------------------------
|
|
62
|
+
重启 argv 除 `-X utf8` 外**保留 `-m` 模块语义**:`python -m md_cg.mcp_server` 若按
|
|
63
|
+
`sys.argv` 原样重启,会退化成「直跑文件」(`sys.path[0]` 变包目录、`__package__`
|
|
64
|
+
丢失),`md_cg/mcp_server.py:3833` 的 `from .datapath import ...` 立即 ImportError
|
|
65
|
+
——本机实测 `python -X utf8 md_cg/mcp_server.py` → rc=1、
|
|
66
|
+
`ImportError: attempted relative import with no known parent package`。而
|
|
67
|
+
`python -m md_cg.mcp_server` 正是 ZCode/DSH 的 mcp.json 接入形态(该文件头注第 14 行)。
|
|
68
|
+
故 `-m` 形态按 `[python, -X, utf8, -m, <模块名>, *sys.argv[1:]]` 重建,其余形态原样
|
|
69
|
+
`*sys.argv`;源码无法重放的解释器形态(`-c` / `-`,从命令行/stdin 读源码)**不重启**,
|
|
70
|
+
只告警——那里重启会把源码丢掉(`python -X utf8 -c` 会转而从 stdin 读代码)。
|
|
71
|
+
"""
|
|
72
|
+
from __future__ import annotations
|
|
73
|
+
|
|
74
|
+
import locale
|
|
75
|
+
import os
|
|
76
|
+
import subprocess
|
|
77
|
+
import sys
|
|
78
|
+
|
|
79
|
+
__all__ = ["ensure_utf8", "launch_hint", "reexec_argv", "NO_REEXEC_ENV",
|
|
80
|
+
"EXIT_UTF8_REQUIRED"]
|
|
81
|
+
|
|
82
|
+
#: 显式退出通道:置真值即不自动重启,改为 fail-fast 非 0 退出
|
|
83
|
+
NO_REEXEC_ENV = "LINGSHU_UTF8_NO_REEXEC"
|
|
84
|
+
#: fail-fast 退出码(非 0;指引文案里点名「怎么改」)
|
|
85
|
+
EXIT_UTF8_REQUIRED = 2
|
|
86
|
+
#: 真值判定集(去空白 + 转小写后比对;未设 / 空串 / 其它值一律视为否)
|
|
87
|
+
_TRUTHY = frozenset(("1", "true", "yes", "on", "y", "t"))
|
|
88
|
+
#: 源码无法重放的解释器形态(`-c` 从命令行读、`-` 从 stdin 读):重启会丢源码
|
|
89
|
+
_UNREBUILDABLE_ARGV0 = frozenset(("-c", "-"))
|
|
90
|
+
#: 结构化退出码:解释器形态无法重放时「不重启也不假装已保证」的退出码(守卫熔断未命中)
|
|
91
|
+
_EXIT_UNREBUILDABLE = 3
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
# 生效条件:env name 存在且其值去空白转小写后落在 _TRUTHY 内返回 True;未设、空串或其它值返回 False。
|
|
95
|
+
def _truthy(name: str) -> bool:
|
|
96
|
+
"""env 真值判定(唯一口径:去空白 + 小写 + 白名单比对)。"""
|
|
97
|
+
return (os.environ.get(name) or "").strip().lower() in _TRUTHY
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
# 生效条件:无入参;把 PYTHONUTF8=1 与 PYTHONIOENCODING=utf-8 写入 os.environ(覆盖旧值,幂等),随后派生的子进程按此继承,无返回值。
|
|
101
|
+
def _set_child_env() -> None:
|
|
102
|
+
"""置子进程继承面(第四条):PYTHONUTF8=1 + PYTHONIOENCODING=utf-8。"""
|
|
103
|
+
os.environ["PYTHONUTF8"] = "1"
|
|
104
|
+
os.environ["PYTHONIOENCODING"] = "utf-8"
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
# 生效条件:无入参;`__main__.__spec__` 同时有 name 与 parent(`python -m pkg.mod` 形态)时返回该模块名,否则返回 None(直跑文件时 `__spec__` 为 None)。
|
|
108
|
+
def _m_module_name() -> str | None:
|
|
109
|
+
"""本进程是否以 `python -m <模块>` 启动;是则返回模块名,否则 None。
|
|
110
|
+
|
|
111
|
+
**单点判别**:`reexec_argv()`(重启 argv)与 `launch_hint()`(fail-fast 指引文案)
|
|
112
|
+
共用本函数——两处各写一份必然漂移,而指引印错的代价是使用者照抄后撞墙(F2)。
|
|
113
|
+
"""
|
|
114
|
+
main = sys.modules.get("__main__")
|
|
115
|
+
spec = getattr(main, "__spec__", None)
|
|
116
|
+
name = getattr(spec, "name", None)
|
|
117
|
+
if name and getattr(spec, "parent", None):
|
|
118
|
+
return name
|
|
119
|
+
return None
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
# 生效条件:entry 为入口标识或 None;本进程经 `python -m` 启动时返回 `-m <模块名>`,其余形态返回 entry 本身(None 时回落占位 `<entry>`)。
|
|
123
|
+
def launch_hint(entry: str | None) -> str:
|
|
124
|
+
"""「照抄即可跑」的启动形态(`-X utf8` 之后的那一段)。
|
|
125
|
+
|
|
126
|
+
-m 形态 → `-m <模块名>`(模块名可被 python 重新 import,等同使用者的原始命令);
|
|
127
|
+
其余形态 → `entry`(通常 `__file__`,绝对路径)。
|
|
128
|
+
"""
|
|
129
|
+
name = _m_module_name()
|
|
130
|
+
if name:
|
|
131
|
+
return "-m %s" % name
|
|
132
|
+
return entry or "<entry>"
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
# 生效条件:无入参;调用 ensure_utf8 的模块 `f_globals` 与 `sys.modules['__main__'].__dict__` 同一时返回 True;取不到调用帧时返回 False(保守:不重启)。
|
|
136
|
+
def _caller_is_process_entry() -> bool:
|
|
137
|
+
"""调用 `ensure_utf8` 的模块是否**就是本进程入口**(`__main__`)。
|
|
138
|
+
|
|
139
|
+
F6 判据本体:只在「本模块即进程入口」时重启/fail-fast——被 import 时重启会吞掉
|
|
140
|
+
调用方正在处理的输入(复核实测:无错误帧、rc=0,静默)。用 `f_globals` 与
|
|
141
|
+
`__main__.__dict__` 的**同一性**比对:`python -m pkg.mod` 下入口模块的 `__name__`
|
|
142
|
+
也是 `"__main__"`,故 -m 与直跑文件两种入口形态得到同一判定。
|
|
143
|
+
"""
|
|
144
|
+
try:
|
|
145
|
+
frame = sys._getframe(1) # ensure_utf8 自身的帧
|
|
146
|
+
globs = frame.f_back.f_globals # 调用 ensure_utf8 的那一帧
|
|
147
|
+
except (ValueError, AttributeError):
|
|
148
|
+
return False # 取不到调用帧:不重启(静默重启的代价更大)
|
|
149
|
+
return globs is getattr(sys.modules.get("__main__"), "__dict__", None)
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
# 生效条件:无入参;sys.argv[0] 为 -c/- (源码不可重放)时返回 None;本进程经 python -m 启动(_m_module_name 非空)时返回 [exe, -X, utf8, -m, 模块名, *sys.argv[1:]];其余形态返回 [exe, -X, utf8, *sys.argv]。
|
|
153
|
+
def reexec_argv() -> list | None:
|
|
154
|
+
"""重启自身的 argv(保留 -m 模块语义);源码不可重放时返回 None。"""
|
|
155
|
+
if sys.argv and sys.argv[0] in _UNREBUILDABLE_ARGV0:
|
|
156
|
+
return None
|
|
157
|
+
name = _m_module_name()
|
|
158
|
+
if name:
|
|
159
|
+
return [sys.executable, "-X", "utf8", "-m", name, *sys.argv[1:]]
|
|
160
|
+
return [sys.executable, "-X", "utf8", *sys.argv]
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
# 生效条件:entry 为入口标识(通常 __file__)或 None,cause 为原因短句;返回「可执行指引」多行文本——启动形态经 launch_hint 复用 -m 判别(-m 入口印 `python -X utf8 -m <模块名>`,其余印 `<entry>`),并含 PYTHONUTF8=1 写法、当前 locale 缺省编码、以及取消 NO_REEXEC_ENV 的出路;全为 ASCII 与中文,无任何凭据。
|
|
164
|
+
def _guidance(entry: str, cause: str) -> str:
|
|
165
|
+
"""fail-fast / 无法重启时的可执行指引(照抄即可跑)。"""
|
|
166
|
+
try:
|
|
167
|
+
pref = locale.getpreferredencoding(False)
|
|
168
|
+
except Exception: # noqa: BLE001
|
|
169
|
+
pref = "?"
|
|
170
|
+
hint = launch_hint(entry) # F2:与 reexec_argv 同一判别
|
|
171
|
+
return (
|
|
172
|
+
"utf8_boot: 入口需要**进程级 UTF-8**,但当前解释器未启用"
|
|
173
|
+
"(sys.flags.utf8_mode=0,locale 缺省编码=%s)。\n"
|
|
174
|
+
" 入口:%s\n"
|
|
175
|
+
" 原因:%s\n"
|
|
176
|
+
"请改用下列任一方式启动(可照抄):\n"
|
|
177
|
+
" python -X utf8 %s\n"
|
|
178
|
+
" PYTHONUTF8=1 python %s # Windows cmd: set PYTHONUTF8=1 && python ...\n"
|
|
179
|
+
"或取消环境变量 %s(让入口自动以 -X utf8 重启自身)。\n"
|
|
180
|
+
% (pref, entry, cause, hint, hint, NO_REEXEC_ENV)
|
|
181
|
+
)
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
# 生效条件:text 给出后优先以 UTF-8 字节写 sys.stderr.buffer(不受控制台代码页影响),buffer 不可用时回落文本层写入;两级都失败则静默返回,无返回值。
|
|
185
|
+
def _emit(text: str) -> None:
|
|
186
|
+
"""把指引写到 stderr——**显式 UTF-8 字节**,不随控制台代码页漂移。"""
|
|
187
|
+
try:
|
|
188
|
+
sys.stderr.buffer.write(text.encode("utf-8"))
|
|
189
|
+
sys.stderr.buffer.flush()
|
|
190
|
+
return
|
|
191
|
+
except Exception: # noqa: BLE001
|
|
192
|
+
pass
|
|
193
|
+
try:
|
|
194
|
+
sys.stderr.write(text)
|
|
195
|
+
sys.stderr.flush()
|
|
196
|
+
except Exception: # noqa: BLE001
|
|
197
|
+
pass
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
# 生效条件:entry 为入口标识或 None;先把 PYTHONUTF8/PYTHONIOENCODING 置入 env;调用方非进程入口(本助手被 import)时立即返回(不重启/不退出/不打日志);sys.flags.utf8_mode 为真时立即返回(不重启、不打日志);为假且 LINGSHU_UTF8_NO_REEXEC 为真时向 stderr 打印可执行指引并以 EXIT_UTF8_REQUIRED 退出;为假且该 env 非真时以 reexec_argv() 重启自身(显式传递 stdin/stdout/stderr 三流)并以子进程退出码退出;重启 argv 为 None(-c/- 形态)或子进程无法启动(OSError)时打印指引并以 _EXIT_UNREBUILDABLE / EXIT_UTF8_REQUIRED 退出;无返回值(不返回即在重启或退出的路上)。
|
|
201
|
+
def ensure_utf8(entry: str | None = None) -> None:
|
|
202
|
+
"""入口自保证 UTF-8 —— 唯一调用点,**必须在任何文件/库 I/O 之前**。
|
|
203
|
+
|
|
204
|
+
生效条件:`utf8_mode` 已开时置 env 后立即返回(不重启、不打日志);未开且
|
|
205
|
+
**本模块不是进程入口**(本助手被 import)时置 env 后立即返回——不重启、不退出、
|
|
206
|
+
不打日志(F6:被 import 时重启会静默吞掉调用方的输入);未开且
|
|
207
|
+
`LINGSHU_UTF8_NO_REEXEC` 为真时向 stderr 打印可执行指引并以
|
|
208
|
+
``EXIT_UTF8_REQUIRED``(2) 退出;未开且该 env 非真时以 ``reexec_argv()`` 重启
|
|
209
|
+
自身(``-X utf8``,显式传递 stdin/stdout/stderr)并以子进程退出码退出——重启后
|
|
210
|
+
子进程 ``utf8_mode`` 已开,故不会二次重启;``-c``/``-`` 形态(源码不可重放)
|
|
211
|
+
不重启,打印指引后以 ``3`` 退出。
|
|
212
|
+
|
|
213
|
+
不适用条件:本进程已在 UTF-8 模式下运行、或本助手是被 import 的(非进程入口)时,
|
|
214
|
+
只置子进程继承面、不做任何重启——即「已在 utf8 模式」「被 import」两者都是幂等
|
|
215
|
+
且安静的(子进程不会再重启)。**入口若以非 `__main__` 形态被 import,则不获得
|
|
216
|
+
重启保证**(这是有意的:静默重启的代价高于少一次保证)。
|
|
217
|
+
"""
|
|
218
|
+
_set_child_env()
|
|
219
|
+
if sys.flags.utf8_mode:
|
|
220
|
+
return # ②:已开 → 不重启、不打日志
|
|
221
|
+
if not _caller_is_process_entry():
|
|
222
|
+
return # F6:被 import → 只置 env,静默
|
|
223
|
+
target = entry or (sys.argv[0] if sys.argv else "<entry>")
|
|
224
|
+
if _truthy(NO_REEXEC_ENV):
|
|
225
|
+
_emit(_guidance(target, "%s 已置真:禁止自动重启" % NO_REEXEC_ENV))
|
|
226
|
+
raise SystemExit(EXIT_UTF8_REQUIRED) # ③:显式退出通道
|
|
227
|
+
argv = reexec_argv()
|
|
228
|
+
if argv is None:
|
|
229
|
+
_emit(_guidance(target, "解释器以 -c/- 读源码,argv 无法重放(不重启)"))
|
|
230
|
+
raise SystemExit(_EXIT_UNREBUILDABLE)
|
|
231
|
+
try:
|
|
232
|
+
proc = subprocess.run(argv, stdin=sys.stdin, stdout=sys.stdout,
|
|
233
|
+
stderr=sys.stderr) # 三流显式传递:字节组帧
|
|
234
|
+
except OSError as exc:
|
|
235
|
+
_emit(_guidance(target, "重启自身失败:%r" % (exc,)))
|
|
236
|
+
raise SystemExit(EXIT_UTF8_REQUIRED)
|
|
237
|
+
raise SystemExit(proc.returncode)
|
package/zcode/AGENTS.md
CHANGED
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
> 本文件由 `scripts/render_discipline.py` 从真源
|
|
4
4
|
> `docs/工作纪律_认知图条目_v1.1.json` 渲染生成,**请勿手改**;改真源后重跑渲染。
|
|
5
|
-
> 真源指纹(SHA256 前16位):
|
|
5
|
+
> 真源指纹(SHA256 前16位):e1e9112a409894aa
|
|
6
6
|
|
|
7
7
|
## 概述
|
|
8
8
|
|
|
9
|
-
工作纪律集: 4条方法论(理论先行/全面处理/白箱方法/根因) + 3条执行(验证/双副本/兜底) + 1条思考(中文思考/协作模式分级) + 1条保密(敏感信息隔离) + 3条图像线(选源护栏/历史查询优先/算法权威唯一) + 1条协作(访谈澄清:先问清再动手) + 1条合规(内容政策合规:公开产物过内容政策+隐私双清单) + 2条执行调度与运行环境(命令执行统一走python/UTF-8: 显式encoding+PYTHONUTF8=1, 规避GBK; 任务派发统一走蜂巢: 任何执行性任务经蜂巢spawn/submit执行并留痕, agent本体只做编排, L1出口=产物落点为只读判定(不改仓库/外部状态)可直跑须留痕) + 1条记忆闭环(任务收尾归档:每次任务执行完只将核心修改(内容/原因/位置/验证结论)按CCG六要素(功能名/生效条件/子功能/执行/验证方式/不适用条件)成文存入灵枢记忆,
|
|
9
|
+
工作纪律集: 4条方法论(理论先行/全面处理/白箱方法/根因) + 3条执行(验证/双副本/兜底) + 1条思考(中文思考/协作模式分级) + 1条保密(敏感信息隔离) + 3条图像线(选源护栏/历史查询优先/算法权威唯一) + 1条协作(访谈澄清:先问清再动手) + 1条合规(内容政策合规:公开产物过内容政策+隐私双清单) + 2条执行调度与运行环境(命令执行统一走python/UTF-8: 显式encoding+PYTHONUTF8=1, 规避GBK, 全仓文本与路径一律UTF-8(无BOM, 中文可进路径), 不做控制台兼容(取用走python); 任务派发统一走蜂巢: 任何执行性任务经蜂巢spawn/submit执行并留痕, agent本体只做编排, L1出口=产物落点为只读判定(不改仓库/外部状态)可直跑须留痕) + 1条记忆闭环(任务收尾归档:每次任务执行完只将核心修改(内容/原因/位置/验证结论)按CCG六要素(功能名/生效条件/子功能/执行/验证方式/不适用条件)成文存入灵枢记忆, 不写中间过程; text 类缺要素即被写入闸门拒并当场返回缺失清单) + 1条信息获取(工作区索引优先: 查工作区文件先读 WORKSPACE_INDEX.md(仓根, 由 scripts/workspace_index.py 从 git 追踪面管线生成), 尚无则先跑 --write 生成再读, 不以重复全盘浏览代替; 索引是会陈化的手工件, 故须管线生成+机械守卫, 否则退化为误导源)
|
|
10
10
|
|
|
11
11
|
## 执行公约
|
|
12
12
|
|
|
@@ -121,16 +121,16 @@
|
|
|
121
121
|
### 15. 命令执行统一走python
|
|
122
122
|
|
|
123
123
|
- **触发**:执行命令|运行测试/脚本|跨进程读写文本
|
|
124
|
-
- **动作**:构造 argv 列表→subprocess.run(capture_output=True, text=True, encoding='utf-8', errors='replace')→env 带 PYTHONUTF8=1→shell=False
|
|
125
|
-
- **不适用**:IDE
|
|
126
|
-
- **声明**:按工作纪律第15条: 命令执行统一走python——argv列表+显式UTF-8+PYTHONUTF8=1, 不经Windows shell, 规避GBK解码异常。
|
|
124
|
+
- **动作**:构造 argv 列表→subprocess.run(capture_output=True, text=True, encoding='utf-8', errors='replace')→env 带 PYTHONUTF8=1→shell=False;边界判据=本次调用是否产出非UTF-8字节流(纯MSYS工具与不起进程的内置工具豁免;原生Windows程序不豁免,须python包装或显式解码)
|
|
125
|
+
- **不适用**:IDE内置工具直调(判据=本次调用是否产出非UTF-8字节流;不起进程的内置工具(Read/Write/Edit/Grep/Glob/WebFetch)与纯MSYS工具(grep/ls/sed)归入本豁免;拉起shell且执行原生Windows程序者(taskkill/wmic/npm.cmd/cargo/where)不属本豁免,仍须python包装或对输出显式解码;2026-09-28使用者裁定)|无跨进程的纯内存计算
|
|
126
|
+
- **声明**:按工作纪律第15条: 命令执行统一走python——argv列表+显式UTF-8+PYTHONUTF8=1, 不经Windows shell, 规避GBK解码异常。 另: 全仓文本与路径/文件名一律UTF-8(中文可进路径), 不做控制台兼容(取用走python, 控制台乱码属显示层)。
|
|
127
127
|
|
|
128
128
|
### 16. 任务收尾归档(记忆闭环)
|
|
129
129
|
|
|
130
130
|
- **触发**:任务执行完成|修改落地后|交付后
|
|
131
|
-
- **动作**:任务收尾→提炼核心修改(内容/原因/位置/验证结论四要素, 不写中间过程/试错/调试/重复确认)→按 CCG 六要素成文(# 功能名/# 生效条件/# 子功能/# 执行/# 验证方式/# 不适用条件 六行缺一不可, 与正文四要素并置)→写入灵枢记忆(认知图/MCP memory)
|
|
131
|
+
- **动作**:任务收尾→提炼核心修改(内容/原因/位置/验证结论四要素, 不写中间过程/试错/调试/重复确认)→按 CCG 六要素成文(# 功能名/# 生效条件/# 子功能/# 执行/# 验证方式/# 不适用条件 六行缺一不可, 与正文四要素并置)→写入灵枢记忆(认知图/MCP memory)——text 类缺要素即被写入闸门拒(REJECT, 当场返回缺失清单, 不是重试无用), 按清单补齐后重写即可→读回确认(写入后发起一次读取查询确认写入成功且可检索)→标注关联条目+更新 subgraph/depends_on
|
|
132
132
|
- **不适用**:情感交互|闲聊|纯查询无改动
|
|
133
|
-
- **声明**:按工作纪律第16条: 任务收尾归档——每次任务执行完只提炼核心修改(内容/原因/位置/验证结论)并按 CCG 六要素(功能名/生效条件/子功能/执行/验证方式/不适用条件)
|
|
133
|
+
- **声明**:按工作纪律第16条: 任务收尾归档——每次任务执行完只提炼核心修改(内容/原因/位置/验证结论)并按 CCG 六要素(功能名/生效条件/子功能/执行/验证方式/不适用条件)成文存入灵枢记忆(text 类六要素缺失会被写入闸门当场拒绝并返回缺失清单——补齐后重写即可, 不必等读回确认才发现), 写入后发起一次读取查询确认写入成功且可检索, 禁写中间过程/试错/调试等无效信息, 与第2条形成「查记忆→执行→写记忆→读回确认」闭环。
|
|
134
134
|
|
|
135
135
|
### 17. 任务派发统一走蜂巢
|
|
136
136
|
|
|
@@ -164,8 +164,8 @@
|
|
|
164
164
|
| 12 | 按工作纪律第12条: 算法权威唯一(线稿=darkline.py/色块=contour_semantics)——选算法查文档, 勿临时切换/漂移; 换算法须记录+更新文档。 |
|
|
165
165
|
| 13 | 按工作纪律第13条: 访谈澄清——先提问确认要做什么,逐轮问到完全清楚才动手;事实自查,决策归使用者,不完全清楚不固化。 |
|
|
166
166
|
| 14 | 按工作纪律第14条: 内容政策合规——对外公开产物必须过「内容政策+隐私」双清单,过滤在生成阶段做;已发布发现违规要删条+重写git历史+通知平台清缓存。 |
|
|
167
|
-
| 15 | 按工作纪律第15条: 命令执行统一走python——argv列表+显式UTF-8+PYTHONUTF8=1, 不经Windows shell, 规避GBK解码异常。 |
|
|
168
|
-
| 16 | 按工作纪律第16条: 任务收尾归档——每次任务执行完只提炼核心修改(内容/原因/位置/验证结论)并按 CCG 六要素(功能名/生效条件/子功能/执行/验证方式/不适用条件)
|
|
167
|
+
| 15 | 按工作纪律第15条: 命令执行统一走python——argv列表+显式UTF-8+PYTHONUTF8=1, 不经Windows shell, 规避GBK解码异常。 另: 全仓文本与路径/文件名一律UTF-8(中文可进路径), 不做控制台兼容(取用走python, 控制台乱码属显示层)。 |
|
|
168
|
+
| 16 | 按工作纪律第16条: 任务收尾归档——每次任务执行完只提炼核心修改(内容/原因/位置/验证结论)并按 CCG 六要素(功能名/生效条件/子功能/执行/验证方式/不适用条件)成文存入灵枢记忆(text 类六要素缺失会被写入闸门当场拒绝并返回缺失清单——补齐后重写即可, 不必等读回确认才发现), 写入后发起一次读取查询确认写入成功且可检索, 禁写中间过程/试错/调试等无效信息, 与第2条形成「查记忆→执行→写记忆→读回确认」闭环。 |
|
|
169
169
|
| 17 | 按工作纪律第17条: 任务派发统一走蜂巢——任何执行性任务经蜂巢 spawn/submit 执行并留痕(spec/status/result), agent本体只做编排; 宿主自带subagent/team不是等价通道, 兜底须声明。L1只读判定(产物落点=不改仓库/外部状态)可直跑, 须输出「L1 直跑:<命令> — 风险/频次/可逆性」留痕。 |
|
|
170
170
|
| 18 | 按工作纪律第18条: 工作区索引优先——查工作区文件先读 WORKSPACE_INDEX.md(仓根, 管线生成); 无则先跑 scripts/workspace_index.py --write 生成再读, 不以重复全盘浏览代替。 |
|
|
171
171
|
|
|
@@ -188,7 +188,7 @@
|
|
|
188
188
|
|
|
189
189
|
三条调用铁律:
|
|
190
190
|
1. **`op` 必填**——漏传会触发参数签名推导兜底(返回标记 `op_derived: true`),复杂任务中也必须显式传,防静默执行错误意图。
|
|
191
|
-
2. **返回 `moved_to: "review_queue"` / `verdict: DEFER
|
|
191
|
+
2. **返回 `moved_to: "review_queue"` / `verdict: DEFER` 时不要重试**——这是校验闸门的正常行为(返回自带 `hint` 说明下一步);落盘须经裁决(`op=review` 的 `decision=accept/reject/edit/merge/noop`,本机工具:`python scripts/review_cli.py list`)。**裁决权(2026-09-28 使用者裁定)**:写入者不得自裁——不得自己写、自己判、无复核一路到底;**经蜂群或验证端复核后,agent 可自行执行裁决**,不必每次转告使用者。**三类例外不适用该授权,必须转交使用者并止步**:①不适用于智能论这类重要协议真源的修改;②不适用于向外部发送信息和数据;③不适用于可能造成信息泄露/病毒/恶意操纵的动作。**`verdict: REJECT` 分两类,处置相反**:① 命中禁止规则(内容政策违规)→ 内容本身不该入库,重试同样结果;② 缺必需要素(`text` 类缺 CCG 六要素)→ **可修正**,按 `verdict.evidence` / `verdict.detail.missing` 给出的**完整缺失清单**补齐六要素后**重写**即落盘(本条未入库、已记入负记忆)——不要把它当「闸门故障」或「重试无用」。
|
|
192
192
|
3. `stg` 同理经 `op` 分发(`timeline` / `relation` / `anchors` 等)。
|
|
193
193
|
|
|
194
194
|
## 收尾强制流程(任务完成时不可跳过)
|