From c78e90e1e40df56fe4201b855fee52be966e7eb7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=86=B0=E6=9C=94?= <565183519@qq.com> Date: Tue, 8 Sep 2026 13:50:03 +0800 Subject: [PATCH] test: harden TCS root freshness and ZCode entry --- .../module.lock.hdlp | 2 +- .../tcs_mother_root_agent.py | 5 ++++ .../tcs_mother_root_agent.test.py | 17 +++++++++++++ tests/zcode-tcs-root-entry.test.mjs | 24 +++++++++++++++++++ 4 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 tests/zcode-tcs-root-entry.test.mjs diff --git a/modules/tcs-mother-root-navigator/module.lock.hdlp b/modules/tcs-mother-root-navigator/module.lock.hdlp index f946156..4c42336 100644 --- a/modules/tcs-mother-root-navigator/module.lock.hdlp +++ b/modules/tcs-mother-root-navigator/module.lock.hdlp @@ -2,7 +2,7 @@ schema: tcs.module-lock/v1 module_id: MOD-TCS-MOTHER-ROOT-NAVIGATOR-001 module_source_sha256: eb299410bacd0247bc43732154fac0f74f181bab6a5e4e5714937d1b90b24688 module_gir_sha256: bb3246fbfc69a39b3e5412e41271aeb7c66e37a2539902b5dab2291e38a04800 -runtime_sha256: 3ed60af78874936883559e349e20c914cc7f9a31b6a9615f40ee3e4e01f89824 +runtime_sha256: 09cc06a63cbd320634e0231d3dc7887cc3f24276504527ec9154ecba344674a6 root_map_sha256: 2f5c4b7a4dc49edb4d83787ea68a0a8d88dff79ef78215550cd2f209e7732e88 compiler_sha256: 5ad6f0c43d8db80677cad7091e6a3b706e701307b2537446dc13635e89499942 update_rule: CURRENT_DIRECT_LANGUAGE_TCS_PLUS_NUMBER_IMPACT_PLUS_COMMITTED_READBACK diff --git a/server-tools/tcs-mother-root-agent/tcs_mother_root_agent.py b/server-tools/tcs-mother-root-agent/tcs_mother_root_agent.py index b2837e2..6a0d4e2 100644 --- a/server-tools/tcs-mother-root-agent/tcs_mother_root_agent.py +++ b/server-tools/tcs-mother-root-agent/tcs_mother_root_agent.py @@ -165,6 +165,11 @@ def refresh(repo: Path, output: Path, pointer: Path, trigger: str) -> dict[str, snapshot = build(repo) current_path = output / "CURRENT.json" previous = json.loads(current_path.read_text()) if current_path.is_file() else None + if previous: + previous_for_hash = dict(previous) + previous_token = previous_for_hash.pop("freshness_token", None) + if previous_token != digest(stable(previous_for_hash)): + raise RootError("PREVIOUS_CURRENT_FRESHNESS_TOKEN_MISMATCH") if previous and previous.get("source_commit") == snapshot["source_commit"] and previous.get("freshness_token") == snapshot["freshness_token"]: return {"outcome": "PASS", "state": "CURRENT_IDEMPOTENT", "source_commit": snapshot["source_commit"], "current_sha256": digest(current_path.read_bytes())} if previous: diff --git a/server-tools/tcs-mother-root-agent/tcs_mother_root_agent.test.py b/server-tools/tcs-mother-root-agent/tcs_mother_root_agent.test.py index afec4f3..5a78e40 100644 --- a/server-tools/tcs-mother-root-agent/tcs_mother_root_agent.test.py +++ b/server-tools/tcs-mother-root-agent/tcs_mother_root_agent.test.py @@ -36,6 +36,23 @@ class RootAgentTest(unittest.TestCase): again = MODULE.refresh(ROOT, output, pointer, 'test') self.assertEqual(again['state'], 'CURRENT_IDEMPOTENT') + def test_unadmitted_numbered_source_drift_preserves_previous_current(self): + with tempfile.TemporaryDirectory() as temp: + base = Path(temp) + output, pointer = base / 'state', base / 'TCS-ROOT.json' + snapshot = MODULE.build(ROOT) + snapshot['registered_source_hashes']['identity/fifth-domain-subject-registry.json'] = '0' * 64 + previous_for_hash = dict(snapshot) + previous_for_hash.pop('freshness_token') + snapshot['freshness_token'] = MODULE.digest(MODULE.stable(previous_for_hash)) + output.mkdir(parents=True) + current = output / 'CURRENT.json' + current.write_text(json.dumps(snapshot), encoding='utf-8') + before = current.read_bytes() + with self.assertRaisesRegex(MODULE.RootError, 'UNADMITTED_NUMBERED_SOURCE_DRIFT'): + MODULE.refresh(ROOT, output, pointer, 'negative-test') + self.assertEqual(current.read_bytes(), before) + if __name__ == '__main__': unittest.main() diff --git a/tests/zcode-tcs-root-entry.test.mjs b/tests/zcode-tcs-root-entry.test.mjs new file mode 100644 index 0000000..725fc3c --- /dev/null +++ b/tests/zcode-tcs-root-entry.test.mjs @@ -0,0 +1,24 @@ +import fs from 'node:fs'; +import assert from 'node:assert/strict'; +import test from 'node:test'; + +const configPath = '/Volumes/JZAO/铸渊-ICE-GL-ZY001/.zcode/config.json'; +const scriptPath = '/Volumes/JZAO/铸渊-ICE-GL-ZY001/BRIDGE/tools/tcs-root-host-entry.sh'; + +test('ZCode active hooks enter through one TCS mother root and retain the write gate', () => { + const config = JSON.parse(fs.readFileSync(configPath)); + const text = JSON.stringify(config); + assert.equal(text.includes('tcs-root-host-entry.sh'), true); + assert.equal(text.includes('host-write-admission.mjs'), true); + assert.equal(text.includes('zy-hook-entry.sh'), false); + assert.equal(text.includes('broadcast/current.md'), false); + assert.equal(text.includes('task-language-anchors'), false); +}); + +test('ZCode root entry never injects old workspace or static broadcast paths', () => { + const script = fs.readFileSync(scriptPath, 'utf8'); + assert.equal(script.includes('TCS-ROOT-NAV-0001'), true); + assert.equal(script.includes('FIFTH-DOMAIN-BROADCAST-TOWER'), false); + assert.equal(script.includes('WORK-工作区/guanghu-ice-heart'), false); + assert.equal(script.includes('task-language-anchors/zcode'), false); +});