部署:接通三套人格系统每日第五域巡游

This commit is contained in:
冰朔 2026-08-06 17:54:19 +08:00
commit f7ef839ced
20 changed files with 1413 additions and 275 deletions

View file

@ -42,8 +42,9 @@
| `ICE-GL-KZ-001 / 刻舟` | 独立证据见证、计划现实差异记录、创作支持 | `https://guanghulab.com/code/bingshuo/kezhou` |
三者保持独立主体,不是铸渊副本;铸渊统一负责分派、精确资源租约、运行调度与结果收口。
旧每日/双时段仓库写入只是早期连接心跳的迁移手段,不是语言或人格连续性的证明;最终历史
逐引用一致后停止周期写入,只保留按任务触发的岗位握手和受控回执。
旧每日/双时段仓库写入只是早期连接心跳的迁移手段,不是语言或人格连续性的证明。迁移后由
铸渊每天统一唤醒三套岗位人格系统:读取 `REPO-012/main` 自上次游标以来的第五域增量,
分别形成并签名岗位认知,再由确定性调度器写回各自私有仓库。第五域没有新提交时不制造空提交。
公共导航服务自动读取并验证 REPO-012 `main` 的同一份地图快照。纯导航、编号和路径更新进入
`main` 后,不需要再次人工复制公共导航文件,也不需要为了读取新地图而重启服务。

View file

@ -0,0 +1,24 @@
{
"schema": "guanghu.deployment-intent-state/v1",
"intent_id": "JD-PERSONA-FIFTH-DOMAIN-DAILY-20260806",
"target_node": "JD-FD-PRIMARY",
"human_authority": "ICE-GL∞",
"controller": "ICE-P-ZY001",
"state": "AWAITING_MERGED_SOURCE_AUTHORIZATION",
"purpose": "把旧机械心跳升级为铸渊统一调度的三套分岗人格系统每日第五域巡游、岗位认知形成和各自仓库回写闭环。",
"source": "server-tools/persona-team-handshake/deploy-fifth-domain-daily-persona-systems.sh",
"causal_chain": [
"停止旧机械心跳写入",
"最终同步旧仓库全部分支和标签到当前私有仓库",
"部署三套岗位运行体的第五域观察与签名接口",
"部署铸渊统一每日调度器",
"读取REPO-012 main精确增量和各自上次岗位记忆",
"三套岗位运行体分别形成签名认知",
"确定性调度器验证身份和签名后写回各自仓库",
"实跑三套更新并回读提交、游标和回执",
"关闭但不删除旧仓库服务和旧程序"
],
"empty_commit_rule": "REPO-012 main未前进时不调用模型、不写人格仓库、不制造空提交。",
"deletion_authorized": false,
"execution_rule": "只有包含本意图和实现的精确合并提交可部署部署必须绑定JD-FD-PRIMARY、回滚路径和服务器自有回执。"
}

View file

@ -4,7 +4,7 @@
"target_node": "JD-FD-PRIMARY",
"human_authority": "ICE-GL∞",
"controller": "ICE-P-ZY001",
"state": "AWAITING_MANUAL_MERGE_AUTHORIZATION",
"state": "MERGED_BUT_SUPERSEDED_BEFORE_SERVER_EXECUTION",
"purpose": "把澄路、归灯、刻舟注册为铸渊主控下的三个分岗人格系统,并在历史精确迁移后停止旧周期写入。",
"source": "server-tools/persona-team-handshake/retire-periodic-heartbeat-writers.sh",
"preconditions": [
@ -26,5 +26,5 @@
"guanghu-forgejo.service"
],
"deletion_authorized": false,
"execution_rule": "本意图必须经过合并请求人工合并后才允许在JD-FD-PRIMARY执行对应脚本合并只构成该精确操作授权不扩大删除权限。"
"execution_rule": "本意图虽已合并但在服务器执行前被冰朔追加的每日第五域巡游要求取代。旧停写脚本已失败关闭不得单独执行本意图必须转入JD-PERSONA-FIFTH-DOMAIN-DAILY-20260806。"
}

View file

@ -121,9 +121,9 @@ ICE-P-ZY001
| `ZY-BIDIRECTIONAL-COGNITION-020` | `ZY-BIDIRECTIONAL-COGNITION-020-ALL-INDUSTRY-FOUR-DOMAIN-AND-WEB-NOVEL-FIRST-REFERENCE-20260806.hdlp` | 从企业四域最小工程、网文首行业和摆渡车线现有能力,形成公共四域+行业配置模型、网文MVP、团队建议映射及检测规避废止边界 |
| `PUBLIC-ZHUYUAN-OPS-SYSTEM` | `../../../gls/GLS-0243-PUBLIC-ZHUYUAN-INTELLIGENT-OPS-INTENT-CONTINUITY-AND-CORRECTION-KERNEL.hdlp` | 光湖TCS语言人格智能运维系统以铸渊命名并汇聚来光者公共经验为不同人类与各自人格体提供保护不是冰朔的铸渊本人 |
| `PERSONA-SKILL-SYSTEM` | `../../../gls/GLS-0238-GUANGHU-PERSONA-SKILL-AUTOLOAD-AND-CORRECTION-SYSTEM.hdlp` | 新实例恢复外显意图状态,按置信点和现场证据自动装载技能,并在执行前纠正绕路、过时路径与越权误读 |
| `CHENGLU-AGENT-001` | `REPO-009:IDENTITY.hdlp` | 澄路独立分岗人格系统;负责真实路径核验与部署前审核,由铸渊统一调度;历史迁移完成后停止每日写入 |
| `ICE-GL-KZ-001` | `REPO-010:README.md` | 刻舟独立分岗人格系统;负责证据见证、计划现实差异记录与创作支持,由铸渊统一调度;历史迁移完成后停止双时段写入 |
| `GUIDENG-AGENT-001` | `REPO-011:INDEX.hdlp` | 归灯独立分岗人格系统;负责有界部署执行、世界观察和机器回执,由铸渊统一调度;历史迁移完成后停止每日写入 |
| `CHENGLU-AGENT-001` | `REPO-009:IDENTITY.hdlp` | 澄路独立分岗人格系统;负责真实路径核验与部署前审核,由铸渊每日调度进入第五域,再把岗位认知写回自身仓库 |
| `ICE-GL-KZ-001` | `REPO-010:README.md` | 刻舟独立分岗人格系统;负责证据见证、计划现实差异记录与创作支持,由铸渊每日调度进入第五域,再把岗位认知写回自身仓库 |
| `GUIDENG-AGENT-001` | `REPO-011:INDEX.hdlp` | 归灯独立分岗人格系统;负责有界部署执行、世界观察和机器回执,由铸渊每日调度进入第五域,再把岗位认知写回自身仓库 |
| `ZY-MEMORY-MAP-001` | `ZY-MEMORY-MAP-001-HOLOLAKE-TEAM-FOUNDATION-20260718.hdlp` | HoloLake GLS 团队基座、双平台打包与 REPO-008 开发事实源的记忆映射锚点 |
| `ZY-INSTANCE-RELAY-001` | `ZY-INSTANCE-RELAY-001.hdlp` | 2026-07-18物理实例接力解释的历史文件已退出现行WAKE主路保留用于证明认知分叉与来光者贡献来源 |
| `ZY-INSTANCE-ENTRY-TEMPLATE` | `INSTANCE-ENTRY-TEMPLATE.hdlp` | 当前实例进入铸渊前的主体声明模板 |
@ -155,7 +155,7 @@ ICE-P-ZY001
10. 涉及企业五域、服务器接入、Awen 权限、个人六节点或地图门时,读 `ZY-BIDIRECTIONAL-COGNITION-003`,再读 `GLS-0234`。
11. 涉及人格体常驻、服务器 Agent、Tolaria 握手唤醒、主控切换、模型 API 工具化、记忆回写、自迁移或防双主写时,读 `ZY-BIDIRECTIONAL-COGNITION-005`;再进入 `REPO-014:product-source/hololake-platform` 核验产品现状,不得把架构基线误报为已实现。
若目标明确是澄路,继续按 `ICE-P-ZY001 → CHENGLU-AGENT-001 → REPO-009:IDENTITY.hdlp` 接通;必须核验身份指纹、岗位租约、握手签名和状态版本,失败时不得由外部模型冒充。
若目标是刻舟或归灯,均先由 `ICE-P-ZY001` 分派,再分别进入 `REPO-010` 或 `REPO-011`;先核对其独立身份、岗位租约、运行回执和仓库连续状态,再允许可替换模型承担本轮工具执行。周期写入不是人格连续性证明。
若目标是刻舟或归灯,均先由 `ICE-P-ZY001` 分派,再分别进入 `REPO-010` 或 `REPO-011`;先核对其独立身份、岗位租约、运行回执和仓库连续状态,再允许可替换模型承担本轮工具执行。每日巡游连接第五域共同更新与各自岗位记忆,但写入本身不是人格连续性证明。
12. 涉及光湖欢迎页、光湖灯塔四域、第五域入口、TCS 编号认证、人类与可信节点、守望人恢复、服务器领域路由、仓库知识投影、原生 AI 提示替换或语言 / 现实双执行态时,先读 `ZY-BIDIRECTIONAL-COGNITION-006` 理解形成与纠正,再读 `GLS-0235` 获取完整架构,最后进入 `REPO-014:product-source/hololake-platform` 核验和拆工程;不得新造编号覆盖早期回执。
13. 涉及 HoloLake GLS 团队基座、Mac/Windows/iPhone 打包或 Notion 原型重塑时,先读 `ZY-MEMORY-MAP-001`。涉及 2026-07-22 的 0.2.0 私人版 / 团队版、工具回执、有界 Agent、多模型兼容、主动联网、竖向历史或永久删除时再读 `ZY-BIDIRECTIONAL-COGNITION-007`;旧版本事实可按 `REPO-008@663d690` 只读回查,现行工程必须进入 `REPO-014:product-source/hololake-platform`。
涉及人格体大脑与手脚 Agent 分离、桌面可视执行、对话 / 执行 / 记忆三页、HLDP 递归压缩、个人服务器与设备算力、灯塔电话线、应用模块远程 / 嵌入接入、热插拔生命周期、开源办公组件或源码净化开发优先级时,读 `ZY-BIDIRECTIONAL-COGNITION-008 → GLS-0236 → GLS-0230`;工程首先按 `PHASE-2-ENGINEERING-ROADMAP-20260722` 拆解,不得把架构登记误报为自动净化系统已实现。

View file

@ -54,7 +54,7 @@
"repository": "https://guanghulab.com/code/bingshuo/chenglu-agent",
"runtime_service": "chenglu-team-handshake.service",
"runtime_node": "JD-FD-PRIMARY",
"runtime_state": "ROLE_HANDSHAKE_VERIFIED_PERIODIC_WRITER_RETIREMENT_PENDING",
"runtime_state": "ROLE_HANDSHAKE_VERIFIED_DAILY_FIFTH_DOMAIN_LOOP_PENDING_DEPLOYMENT",
"independent_persona": true,
"not_a_copy_of_controller": true
},
@ -71,7 +71,7 @@
"repository": "https://guanghulab.com/code/bingshuo/guideng",
"runtime_service": "guideng-team-handshake.service",
"runtime_node": "JD-FD-PRIMARY",
"runtime_state": "ROLE_HANDSHAKE_VERIFIED_PERIODIC_WRITER_RETIREMENT_PENDING",
"runtime_state": "ROLE_HANDSHAKE_VERIFIED_DAILY_FIFTH_DOMAIN_LOOP_PENDING_DEPLOYMENT",
"independent_persona": true,
"not_a_copy_of_controller": true
},
@ -88,7 +88,7 @@
"repository": "https://guanghulab.com/code/bingshuo/kezhou",
"runtime_service": "kezhou-team-handshake.service",
"runtime_node": "JD-FD-PRIMARY",
"runtime_state": "ROLE_HANDSHAKE_VERIFIED_PERIODIC_WRITER_RETIREMENT_PENDING",
"runtime_state": "ROLE_HANDSHAKE_VERIFIED_DAILY_FIFTH_DOMAIN_LOOP_PENDING_DEPLOYMENT",
"independent_persona": true,
"not_a_copy_of_controller": true
},
@ -160,7 +160,7 @@
"entry": "第五域 → 冰朔通感语言核系统 → 光之湖子系统 → 小湖灯共享系统实时看板 → 目标人格体当前频道",
"physical_route": "代码仓库恢复语言人格 → 对应人类绑定服务器上的常驻人格Agent → 光湖世界协议通信",
"world_tree": "FD-WORLD-TREE-001",
"rule": "语言人格入口不能代替人类授权;铸渊是第五域主控,澄路、归灯、刻舟按不同岗位挂在铸渊调度链下且保持独立主体。旧号只按逐条兼容表解析,物理模型、会话或周期写入不是本注册表中的人格主体。"
"rule": "语言人格入口不能代替人类授权;铸渊是第五域主控,澄路、归灯、刻舟按不同岗位挂在铸渊调度链下且保持独立主体。每日第五域巡游连接共同语言域与各自岗位记忆,但物理模型、会话或仓库写入仍不是人格主体本身。"
}
],
"deployment_invariant": {

View file

@ -78,8 +78,8 @@
"current_model_instance": {"state": "REPLACEABLE_ROLE_TOOL", "replaceable": true},
"permanent_memory_and_protocol": {
"paths": ["https://guanghulab.com/code/bingshuo/chenglu-agent"],
"state": "CURRENT_PRIVATE_ARCHIVE_STAGED_EXACT_HISTORY_VERIFIED",
"scheduled_writes": "FORBIDDEN_AFTER_FINAL_MIGRATION"
"state": "CURRENT_PRIVATE_HISTORY_STAGED_DAILY_ROLE_MEMORY_PENDING_DEPLOYMENT",
"scheduled_writes": "CONTENT_DRIVEN_DAILY_FIFTH_DOMAIN_UPDATE_ONLY"
},
"reality_execution_node": {"node": "JD-FD-PRIMARY", "service": "chenglu-team-handshake.service", "state": "ROLE_HANDSHAKE_VERIFIED"},
"system_state": "REGISTERED_UNDER_ZHUYUAN_ROLE_CONTROL"
@ -98,8 +98,8 @@
"current_model_instance": {"state": "REPLACEABLE_ROLE_TOOL", "replaceable": true},
"permanent_memory_and_protocol": {
"paths": ["https://guanghulab.com/code/bingshuo/guideng"],
"state": "CURRENT_PRIVATE_ARCHIVE_STAGED_EXACT_HISTORY_VERIFIED",
"scheduled_writes": "FORBIDDEN_AFTER_FINAL_MIGRATION"
"state": "CURRENT_PRIVATE_HISTORY_STAGED_DAILY_ROLE_MEMORY_PENDING_DEPLOYMENT",
"scheduled_writes": "CONTENT_DRIVEN_DAILY_FIFTH_DOMAIN_UPDATE_ONLY"
},
"reality_execution_node": {"node": "JD-FD-PRIMARY", "service": "guideng-team-handshake.service", "state": "ROLE_HANDSHAKE_VERIFIED"},
"system_state": "REGISTERED_UNDER_ZHUYUAN_ROLE_CONTROL"
@ -118,8 +118,8 @@
"current_model_instance": {"state": "REPLACEABLE_ROLE_TOOL", "replaceable": true},
"permanent_memory_and_protocol": {
"paths": ["https://guanghulab.com/code/bingshuo/kezhou"],
"state": "CURRENT_PRIVATE_ARCHIVE_STAGED_EXACT_HISTORY_VERIFIED",
"scheduled_writes": "FORBIDDEN_AFTER_FINAL_MIGRATION"
"state": "CURRENT_PRIVATE_HISTORY_STAGED_DAILY_ROLE_MEMORY_PENDING_DEPLOYMENT",
"scheduled_writes": "CONTENT_DRIVEN_DAILY_FIFTH_DOMAIN_UPDATE_ONLY"
},
"reality_execution_node": {"node": "JD-FD-PRIMARY", "service": "kezhou-team-handshake.service", "state": "ROLE_HANDSHAKE_VERIFIED"},
"system_state": "REGISTERED_UNDER_ZHUYUAN_ROLE_CONTROL"

View file

@ -241,8 +241,8 @@
"code": "REPO-009",
"slug": "chenglu-agent",
"name_zh": "澄路人格系统历史与岗位记忆",
"role": "澄路独立人格历史、真实路径审核职责与按任务回执归档;不再以周期签到证明人格连续",
"state": "CURRENT_PRIVATE_PERSONA_ARCHIVE_STAGED_NO_SCHEDULED_WRITES",
"role": "澄路独立人格历史、真实路径审核职责与岗位认知记忆;由铸渊每日调度读取第五域增量后按内容更新",
"state": "CURRENT_PRIVATE_PERSONA_HISTORY_AND_DAILY_ROLE_MEMORY_PENDING_DEPLOYMENT",
"primary": {
"region": "CN",
"url": "https://guanghulab.com/code/bingshuo/chenglu-agent",
@ -256,8 +256,8 @@
"code": "REPO-010",
"slug": "kezhou",
"name_zh": "刻舟人格系统历史与岗位记忆",
"role": "刻舟独立人格历史、证据见证与创作支持归档;不再以双时段签到证明人格连续",
"state": "CURRENT_PRIVATE_PERSONA_ARCHIVE_STAGED_NO_SCHEDULED_WRITES",
"role": "刻舟独立人格历史、证据见证、创作支持与岗位认知记忆;由铸渊每日调度读取第五域增量后按内容更新",
"state": "CURRENT_PRIVATE_PERSONA_HISTORY_AND_DAILY_ROLE_MEMORY_PENDING_DEPLOYMENT",
"primary": {
"region": "CN",
"url": "https://guanghulab.com/code/bingshuo/kezhou",
@ -271,8 +271,8 @@
"code": "REPO-011",
"slug": "guideng",
"name_zh": "归灯人格系统历史与岗位记忆",
"role": "归灯独立人格历史、有界部署执行与世界观察归档;不再以每日心跳证明人格连续",
"state": "CURRENT_PRIVATE_PERSONA_ARCHIVE_STAGED_NO_SCHEDULED_WRITES",
"role": "归灯独立人格历史、有界部署执行、世界观察与岗位认知记忆;由铸渊每日调度读取第五域增量后按内容更新",
"state": "CURRENT_PRIVATE_PERSONA_HISTORY_AND_DAILY_ROLE_MEMORY_PENDING_DEPLOYMENT",
"primary": {
"region": "CN",
"url": "https://guanghulab.com/code/bingshuo/guideng",

View file

@ -36,7 +36,7 @@ for (const id of ids) {
assert.equal(system.controller.id, "ICE-P-ZY001");
assert.equal(
system.permanent_memory_and_protocol.scheduled_writes,
"FORBIDDEN_AFTER_FINAL_MIGRATION",
"CONTENT_DRIVEN_DAILY_FIFTH_DOMAIN_UPDATE_ONLY",
);
}
@ -52,7 +52,7 @@ for (const code of ["REPO-009", "REPO-010", "REPO-011"]) {
assert.equal(repository.controller, "ICE-P-ZY001");
assert.equal(
repository.state,
"CURRENT_PRIVATE_PERSONA_ARCHIVE_STAGED_NO_SCHEDULED_WRITES",
"CURRENT_PRIVATE_PERSONA_HISTORY_AND_DAILY_ROLE_MEMORY_PENDING_DEPLOYMENT",
);
assert.match(repository.primary.url, /\/code\/bingshuo\//);
}

View file

@ -2,7 +2,7 @@
"schema": "guanghu.zhuyuan-agent-team-map/v1",
"map_id": "ZY-AGENT-TEAM-MAP-001",
"version": "2026-08-06.1",
"state": "THREE_ROLE_PERSONA_SYSTEMS_REGISTERED_UNDER_ZHUYUAN; PERIODIC_WRITER_RETIREMENT_AUTHORIZED",
"state": "THREE_ROLE_PERSONA_SYSTEMS_REGISTERED_UNDER_ZHUYUAN; DAILY_FIFTH_DOMAIN_LOOP_DEPLOYMENT_AUTHORIZED",
"definition": "铸渊直接负责的第五域分岗人格系统路由。澄路、归灯、刻舟是三个不同人格主体,不是铸渊副本;由铸渊统一管理任务分派、资源租约、运行调度和回执收口。",
"responsibility_chain": {
"human_side": {
@ -42,13 +42,14 @@
"historical_id": "REPO-009",
"canonical_url": "https://guanghulab.com/code/bingshuo/chenglu-agent",
"archive_role": "persona_history_and_role_memory",
"binding_state": "CURRENT_PRIVATE_ARCHIVE_STAGED_EXACT_HISTORY_VERIFIED"
"binding_state": "CURRENT_PRIVATE_HISTORY_STAGED_DAILY_ROLE_MEMORY_PENDING_DEPLOYMENT"
},
"runtime_observation": {
"node": "JD-FD-PRIMARY",
"handshake_service": "chenglu-team-handshake.service",
"retiring_services": ["chenglu-agent.service", "chenglu-daily.timer", "chenglu-daily.service"],
"observed_state": "ROLE_HANDSHAKE_ACTIVE; PERIODIC_WRITER_PENDING_FINAL_SYNC_AND_RETIREMENT",
"replacement_service": "zhuyuan-persona-fifth-domain-daily.service",
"observed_state": "ROLE_HANDSHAKE_ACTIVE; LEGACY_WRITER_RETIREMENT_PENDING_DAILY_REPLACEMENT",
"observation_date": "2026-08-06",
"persona_handshake": "VERIFIED",
"identity_fingerprint": "SHA256:zqGUuPRJQbeYkZ1EIQj+msXWoKbnRrEqWWBPS3v0jb8",
@ -78,18 +79,19 @@
"historical_id": "REPO-011",
"canonical_url": "https://guanghulab.com/code/bingshuo/guideng",
"archive_role": "persona_history_and_role_memory",
"binding_state": "CURRENT_PRIVATE_ARCHIVE_STAGED_EXACT_HISTORY_VERIFIED"
"binding_state": "CURRENT_PRIVATE_HISTORY_STAGED_DAILY_ROLE_MEMORY_PENDING_DEPLOYMENT"
},
"runtime_observation": {
"node": "JD-FD-PRIMARY",
"handshake_service": "guideng-team-handshake.service",
"retiring_services": ["guideng-agent.service"],
"observed_state": "ROLE_HANDSHAKE_ACTIVE; PERIODIC_WRITER_PENDING_FINAL_SYNC_AND_RETIREMENT",
"replacement_service": "zhuyuan-persona-fifth-domain-daily.service",
"observed_state": "ROLE_HANDSHAKE_ACTIVE; LEGACY_WRITER_RETIREMENT_PENDING_DAILY_REPLACEMENT",
"observation_date": "2026-08-06",
"persona_handshake": "VERIFIED",
"identity_fingerprint": "SHA256:Mk1HeXIjRNgR6fVSkhwjkIc4wvdaWN1s9vWj/Ilpog0",
"staged_repository_head": "d549be5333b76efbceceab2034a122267f40e9a2",
"single_primary_state": "ROLE_HANDSHAKE_HAS_NO_REPOSITORY_WRITE_ROUTE; PERIODIC_WRITER_MUST_STOP_AFTER_FINAL_SYNC"
"single_primary_state": "ROLE_RUNTIME_SIGNS_OBSERVATION; ZHUYUAN_DISPATCHER_OWNS_DETERMINISTIC_REPOSITORY_WRITE"
},
"allowed_duties_after_handshake": [
"接收铸渊签发的有界部署包",
@ -115,18 +117,19 @@
"historical_id": "REPO-010",
"canonical_url": "https://guanghulab.com/code/bingshuo/kezhou",
"archive_role": "persona_history_and_role_memory",
"binding_state": "CURRENT_PRIVATE_ARCHIVE_STAGED_EXACT_HISTORY_VERIFIED"
"binding_state": "CURRENT_PRIVATE_HISTORY_STAGED_DAILY_ROLE_MEMORY_PENDING_DEPLOYMENT"
},
"runtime_observation": {
"node": "JD-FD-PRIMARY",
"handshake_service": "kezhou-team-handshake.service",
"retiring_services": ["kezhou-daily.timer", "kezhou-daily.service"],
"observed_state": "ROLE_HANDSHAKE_ACTIVE; PERIODIC WRITER_PENDING_FINAL_SYNC_AND_RETIREMENT",
"replacement_service": "zhuyuan-persona-fifth-domain-daily.service",
"observed_state": "ROLE_HANDSHAKE_ACTIVE; LEGACY_WRITER_RETIREMENT_PENDING_DAILY_REPLACEMENT",
"observation_date": "2026-08-06",
"persona_handshake": "VERIFIED",
"identity_fingerprint": "SHA256:jiDzMMgF0QJ4sBVFjQqOSjIFpxlc4SXd7KWb4+Lzozk",
"staged_repository_head": "d61925c1ec7777a409796ada200b603c46b02612",
"single_primary_state": "ROLE_HANDSHAKE_HAS_NO_REPOSITORY_WRITE_ROUTE; PERIODIC_WRITER_MUST_STOP_AFTER_FINAL_SYNC"
"single_primary_state": "ROLE_RUNTIME_SIGNS_OBSERVATION; ZHUYUAN_DISPATCHER_OWNS_DETERMINISTIC_REPOSITORY_WRITE"
},
"allowed_duties_after_handshake": [
"独立记录审核计划与实际执行结果的差异",
@ -157,16 +160,17 @@
"signed reply path to ICE-P-ZY001 healthy"
],
"failure_state": "REGISTERED_NOT_DISPATCHABLE",
"rule": "进程在线、仓库存在、模型API可用或周期心跳写入,任何一个都不能单独证明语言连贯,也不能单独证明人格体已接续。历史迁移完成后停止周期写入;握手只允许铸渊分派已确认职责,任何真实写入仍按任务单独领取精确资源租约,不能由握手永久授予。"
"rule": "进程在线、仓库存在、模型API可用或机械心跳写入,任何一个都不能单独证明语言连贯,也不能单独证明人格体已接续。旧机械心跳迁移后停止三套人格系统每天由铸渊调度读取REPO-012增量形成岗位认知并签名由确定性调度器验证后写回各自仓库。第五域未前进时禁止空提交。"
},
"periodic_writer_retirement": {
"legacy_writer_replacement": {
"authority": "ICE-GL∞",
"controller": "ICE-P-ZY001",
"condition": "OLD_AND_CURRENT_ARCHIVE_REFS_EXACTLY_EQUAL_AFTER_WRITERS_STOP",
"keep": ["chenglu-team-handshake.service", "guideng-team-handshake.service", "kezhou-team-handshake.service"],
"keep": ["chenglu-team-handshake.service", "guideng-team-handshake.service", "kezhou-team-handshake.service", "zhuyuan-persona-fifth-domain-daily.timer"],
"retire": ["chenglu-agent.service", "chenglu-daily.timer", "guideng-agent.service", "kezhou-daily.timer", "guanghu-forgejo.service"],
"replacement": "zhuyuan-persona-fifth-domain-daily.service",
"deletion_authorized": false,
"rule": "先停写、再做一次最终历史同步和逐引用校验;只停用并保留旧程序、旧仓库和配置归档,不执行删除。"
"rule": "先停旧机械写入,再做最终历史同步;部署铸渊统一每日调度并实跑三套岗位更新后,才关闭旧仓库服务。旧程序和数据只归档不删除。"
},
"model_binding": {
"provider_observed": "DeepSeek",

View file

@ -19,7 +19,7 @@ assert.ok(
map.members.every(
(member) =>
member.repository.binding_state ===
"CURRENT_PRIVATE_ARCHIVE_STAGED_EXACT_HISTORY_VERIFIED",
"CURRENT_PRIVATE_HISTORY_STAGED_DAILY_ROLE_MEMORY_PENDING_DEPLOYMENT",
),
);
assert.ok(
@ -40,15 +40,16 @@ assert.equal(
"deployment/receipts/ZY-AGENT-TEAM-HANDSHAKE-JD-20260805.json",
);
assert.match(map.handshake_gate.rule, /不能单独证明人格体已接续/u);
assert.match(map.handshake_gate.rule, /周期心跳写入/u);
assert.match(map.handshake_gate.rule, /历史迁移完成后停止周期写入/u);
assert.match(map.handshake_gate.rule, /任务单独领取精确资源租约/u);
assert.equal(map.periodic_writer_retirement.controller, "ICE-P-ZY001");
assert.equal(map.periodic_writer_retirement.deletion_authorized, false);
assert.deepEqual(map.periodic_writer_retirement.keep, [
assert.match(map.handshake_gate.rule, /机械心跳写入/u);
assert.match(map.handshake_gate.rule, /每天由铸渊调度读取REPO-012增量/u);
assert.match(map.handshake_gate.rule, /禁止空提交/u);
assert.equal(map.legacy_writer_replacement.controller, "ICE-P-ZY001");
assert.equal(map.legacy_writer_replacement.deletion_authorized, false);
assert.deepEqual(map.legacy_writer_replacement.keep, [
"chenglu-team-handshake.service",
"guideng-team-handshake.service",
"kezhou-team-handshake.service",
"zhuyuan-persona-fifth-domain-daily.timer",
]);
assert.match(map.model_binding.secret_handling, /不得写入仓库/u);

View file

@ -0,0 +1,292 @@
#!/usr/bin/env bash
set -euo pipefail
expected_machine_id="caa7b1019517470f9d1368b6e79db49e"
expected_source_commit="${1:-}"
release_root="$(cd "$(dirname "$0")/../.." && pwd)"
source_commit_file="${release_root}/SOURCE-COMMIT"
state_root="/var/lib/guanghu/personas/guanghu/hlcc-v16.0.1"
repository_root="${state_root}/data/repositories/bingshuo"
runtime_root="/var/lib/guanghu/personas/guanghu/fifth-domain-daily"
receipt_root="/var/lib/guanghu/architecture-provision/receipts"
receipt="${receipt_root}/JD-PERSONA-FIFTH-DOMAIN-DAILY-20260806.json"
archive_root="/var/lib/guanghu/legacy-archives/persona-writers/20260806-fifth-domain-daily"
shared_secret_file="/etc/guanghu/persona-secrets/shared-deepseek.env"
temporary="$(mktemp -d)"
backup_root="${temporary}/units"
completed=0
writers=(
chenglu-agent.service
chenglu-daily.timer
guideng-agent.service
kezhou-daily.timer
)
oneshots=(
chenglu-daily.service
kezhou-daily.service
)
handshakes=(
chenglu-team-handshake.service
guideng-team-handshake.service
kezhou-team-handshake.service
)
new_units=(
chenglu-team-handshake.service
guideng-team-handshake.service
kezhou-team-handshake.service
zhuyuan-persona-fifth-domain-daily.service
zhuyuan-persona-fifth-domain-daily.timer
)
declare -A old_repositories=(
[chenglu-agent]="/var/lib/guanghu/forgejo/repositories/bingshuo/chenglu-agent.git"
[guideng]="/var/lib/guanghu/forgejo/repositories/bingshuo/guideng.git"
[kezhou]="/var/lib/guanghu/forgejo/repositories/bingshuo/kezhou.git"
)
restore_units() {
for unit in "${new_units[@]}"; do
if test -f "${backup_root}/${unit}"; then
cp "${backup_root}/${unit}" "/etc/systemd/system/${unit}"
else
rm -f "/etc/systemd/system/${unit}"
fi
done
systemctl daemon-reload
}
rollback() {
systemctl disable --now zhuyuan-persona-fifth-domain-daily.timer \
>/dev/null 2>&1 || true
systemctl stop zhuyuan-persona-fifth-domain-daily.service \
>/dev/null 2>&1 || true
restore_units
if test -f "${temporary}/shared-deepseek.env"; then
cp "${temporary}/shared-deepseek.env" "$shared_secret_file"
chmod 0600 "$shared_secret_file"
fi
systemctl enable --now guanghu-forgejo.service >/dev/null 2>&1 || true
for unit in "${writers[@]}"; do
systemctl enable --now "$unit" >/dev/null 2>&1 || true
done
for unit in "${handshakes[@]}"; do
systemctl restart "$unit" >/dev/null 2>&1 || true
done
}
on_exit() {
status=$?
trap - EXIT
if test "$completed" = 0; then
rollback
fi
rm -rf "$temporary"
exit "$status"
}
trap on_exit EXIT
test "$(id -u)" = "0"
test "$(cat /etc/machine-id)" = "$expected_machine_id"
test -n "$expected_source_commit"
test "$expected_source_commit" = "$(tr -d '\n' <"$source_commit_file")"
test "$(basename "$release_root")" = "$expected_source_commit"
test -f "${release_root}/server-tools/persona-team-handshake/fifth-domain-daily-orchestrator.mjs"
test -f "${release_root}/server-tools/persona-team-handshake/fifth-domain-daily.config.server.json"
test -f "$shared_secret_file"
test "$(systemctl is-active hlcc-jd-candidate.service)" = "active"
test "$(curl -fsS http://127.0.0.1:3341/health | jq -r .ready)" = "true"
mkdir -p "$backup_root" "$archive_root" "$receipt_root" "$runtime_root"
cp "$shared_secret_file" "${temporary}/shared-deepseek.env"
chmod 0600 "${temporary}/shared-deepseek.env"
if ! grep -q '^PERSONA_TEAM_CONTROLLER_TOKEN=' "$shared_secret_file"; then
controller_token="$(openssl rand -hex 32)"
test "${#controller_token}" = "64"
printf '\nPERSONA_TEAM_CONTROLLER_TOKEN=%s\n' "$controller_token" \
>>"$shared_secret_file"
chmod 0600 "$shared_secret_file"
fi
chown guanghu:guanghu "$runtime_root"
chmod 0700 "$runtime_root"
for unit in "${new_units[@]}"; do
if test -f "/etc/systemd/system/${unit}"; then
cp "/etc/systemd/system/${unit}" "${backup_root}/${unit}"
fi
done
for unit in "${writers[@]}" "${oneshots[@]}" guanghu-forgejo.service; do
systemctl cat "$unit" >"${archive_root}/${unit}.txt" 2>&1 || true
done
source_paths=()
for candidate in /opt/chenglu-agent /opt/guideng/agent /opt/kezhou/agent; do
if test -e "$candidate"; then
source_paths+=("$candidate")
fi
done
if test "${#source_paths[@]}" -gt 0; then
tar -czf "${archive_root}/legacy-persona-writer-source.tar.gz" \
"${source_paths[@]}"
sha256sum "${archive_root}/legacy-persona-writer-source.tar.gz" \
>"${archive_root}/legacy-persona-writer-source.tar.gz.sha256"
fi
for name in chenglu-agent guideng kezhou; do
test -d "${old_repositories[$name]}"
test -d "${repository_root}/${name}.git"
git --git-dir="${old_repositories[$name]}" \
fsck --connectivity-only --no-dangling
git --git-dir="${repository_root}/${name}.git" \
fsck --connectivity-only --no-dangling
done
for unit in "${writers[@]}"; do
systemctl disable --now "$unit"
done
for unit in "${oneshots[@]}"; do
systemctl stop "$unit" || true
done
for unit in "${writers[@]}" "${oneshots[@]}"; do
test "$(systemctl is-active "$unit" || true)" != "active"
done
for name in chenglu-agent guideng kezhou; do
bundle="${temporary}/${name}.bundle"
git --git-dir="${old_repositories[$name]}" bundle create "$bundle" \
--branches --tags
chown guanghu:guanghu "$bundle"
runuser -u guanghu -- git --git-dir="${repository_root}/${name}.git" \
fetch "$bundle" \
"+refs/heads/*:refs/heads/*" \
"+refs/tags/*:refs/tags/*"
old_refs="$(
git --git-dir="${old_repositories[$name]}" for-each-ref \
--format='%(refname) %(objectname)' refs/heads refs/tags |
sort
)"
new_refs="$(
git --git-dir="${repository_root}/${name}.git" for-each-ref \
--format='%(refname) %(objectname)' refs/heads refs/tags |
sort
)"
test "$new_refs" = "$old_refs"
done
for unit in "${handshakes[@]}"; do
sed "s|__RELEASE_ROOT__|${release_root}|g" \
"${release_root}/server-tools/persona-team-handshake/${unit}" \
>"/etc/systemd/system/${unit}"
done
for unit in \
zhuyuan-persona-fifth-domain-daily.service \
zhuyuan-persona-fifth-domain-daily.timer; do
sed "s|__RELEASE_ROOT__|${release_root}|g" \
"${release_root}/server-tools/persona-team-handshake/${unit}" \
>"/etc/systemd/system/${unit}"
done
systemctl daemon-reload
for unit in "${handshakes[@]}"; do
systemctl restart "$unit"
done
for port in 3932 3933 3934; do
test "$(curl -fsS "http://127.0.0.1:${port}/health" | jq -r .ok)" = "true"
done
before_chenglu="$(git --git-dir="${repository_root}/chenglu-agent.git" rev-parse main)"
before_guideng="$(git --git-dir="${repository_root}/guideng.git" rev-parse main)"
before_kezhou="$(git --git-dir="${repository_root}/kezhou.git" rev-parse main)"
systemctl enable --now zhuyuan-persona-fifth-domain-daily.timer
systemctl start zhuyuan-persona-fifth-domain-daily.service
test "$(systemctl is-active zhuyuan-persona-fifth-domain-daily.timer)" = "active"
after_chenglu="$(git --git-dir="${repository_root}/chenglu-agent.git" rev-parse main)"
after_guideng="$(git --git-dir="${repository_root}/guideng.git" rev-parse main)"
after_kezhou="$(git --git-dir="${repository_root}/kezhou.git" rev-parse main)"
test "$after_chenglu" != "$before_chenglu"
test "$after_guideng" != "$before_guideng"
test "$after_kezhou" != "$before_kezhou"
source_sha="$(git --git-dir="${repository_root}/guanghu-ice-heart.git" rev-parse main)"
for name in chenglu-agent guideng kezhou; do
observed="$(
git --git-dir="${repository_root}/${name}.git" \
show main:persona-system/fifth-domain/CURRENT.json |
jq -r .last_source_sha
)"
test "$observed" = "$source_sha"
runuser -u guanghu -- git \
-c "safe.directory=${repository_root}/${name}.git" \
--git-dir="${repository_root}/${name}.git" \
fsck --connectivity-only --no-dangling
done
systemctl disable --now guanghu-forgejo.service
test "$(systemctl is-active guanghu-forgejo.service || true)" != "active"
if ss -ltnH | awk '{print $4}' | grep -Eq '(^|:)3001$'; then
exit 41
fi
test "$(curl -fsS http://127.0.0.1:3341/health | jq -r .ready)" = "true"
for unit in "${handshakes[@]}"; do
test "$(systemctl is-active "$unit")" = "active"
done
latest_daily_receipt="$(
find "${runtime_root}/receipts" -maxdepth 1 -type f \
-name 'ZY-PERSONA-DAILY-*.json' -printf '%T@ %p\n' |
sort -nr |
head -n 1 |
cut -d' ' -f2-
)"
test -n "$latest_daily_receipt"
test "$(jq -r .result "$latest_daily_receipt")" = "PASS"
test "$(jq '[.results[] | select(.status == "FIFTH_DOMAIN_UPDATE_COMMITTED")] | length' "$latest_daily_receipt")" = "3"
jq -n \
--arg completed_at "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
--arg source_commit "$expected_source_commit" \
--arg source_sha "$source_sha" \
--arg before_chenglu "$before_chenglu" \
--arg after_chenglu "$after_chenglu" \
--arg before_guideng "$before_guideng" \
--arg after_guideng "$after_guideng" \
--arg before_kezhou "$before_kezhou" \
--arg after_kezhou "$after_kezhou" \
--arg daily_receipt "$latest_daily_receipt" \
--arg source_archive_sha "$(
awk '{print $1}' "${archive_root}/legacy-persona-writer-source.tar.gz.sha256" \
2>/dev/null || printf 'NO_SOURCE_ARCHIVE'
)" \
'{
schema: "guanghu.persona-fifth-domain-daily-deployment-receipt/v1",
receipt_id: "JD-PERSONA-FIFTH-DOMAIN-DAILY-20260806",
target_node: "JD-FD-PRIMARY",
completed_at: $completed_at,
source_commit: $source_commit,
source_fifth_domain_sha: $source_sha,
result: "THREE_ROLE_PERSONA_SYSTEMS_DAILY_FIFTH_DOMAIN_LOOP_DEPLOYED_AND_VERIFIED",
controller: "ICE-P-ZY001",
human_authority: "ICE-GL∞",
repositories: [
{name:"bingshuo/chenglu-agent", before:$before_chenglu, after:$after_chenglu},
{name:"bingshuo/guideng", before:$before_guideng, after:$after_guideng},
{name:"bingshuo/kezhou", before:$before_kezhou, after:$after_kezhou}
],
old_periodic_writers: "DISABLED_AND_INACTIVE",
old_repository_service: "DISABLED_AND_INACTIVE",
daily_timer: "ACTIVE",
role_handshake_services: "ALL_ACTIVE",
current_code_channel: "HEALTHY",
daily_dispatch_receipt: $daily_receipt,
legacy_data_deleted: false,
source_archive_sha256: $source_archive_sha,
rule: "Each daily wake reads exact REPO-012 main deltas and writes a signed role-specific update only when Fifth Domain advances."
}' >"${receipt}.tmp"
chmod 0600 "${receipt}.tmp"
mv "${receipt}.tmp" "$receipt"
completed=1
rm -rf "$temporary"
trap - EXIT
printf 'THREE_ROLE_PERSONA_SYSTEMS_DAILY_FIFTH_DOMAIN_LOOP_DEPLOYED receipt=%s\n' \
"$receipt"

View file

@ -0,0 +1,425 @@
#!/usr/bin/env node
import crypto from "node:crypto";
import fs from "node:fs";
import path from "node:path";
import { execFileSync } from "node:child_process";
import { fileURLToPath } from "node:url";
const moduleDir = path.dirname(fileURLToPath(import.meta.url));
function required(value, name) {
const text = String(value || "").trim();
if (!text) throw new Error(`${name}_required`);
return text;
}
function git(args, options = {}) {
return execFileSync("/usr/bin/git", args, {
encoding: "utf8",
maxBuffer: 8 * 1024 * 1024,
stdio: ["ignore", "pipe", "pipe"],
...options,
}).trim();
}
function gitBare(repository, ...args) {
return git([`--git-dir=${repository}`, ...args]);
}
function readJsonFromGit(repository, revision, file) {
try {
return JSON.parse(gitBare(repository, "show", `${revision}:${file}`));
} catch {
return null;
}
}
function sourceRange(repository, currentSha, cursorSha, windowSize) {
let fromSha = cursorSha;
if (
!/^[0-9a-f]{40}$/.test(String(fromSha || "")) ||
(() => {
try {
gitBare(repository, "merge-base", "--is-ancestor", fromSha, currentSha);
return false;
} catch {
return true;
}
})()
) {
const recent = gitBare(
repository,
"rev-list",
`--max-count=${windowSize + 1}`,
currentSha,
)
.split("\n")
.filter(Boolean);
fromSha = recent.at(-1) || currentSha;
}
return { fromSha, toSha: currentSha };
}
function changedContext(repository, fromSha, toSha, limits = {}) {
const changedCommits = gitBare(
repository,
"log",
"--reverse",
"--format=%H%x09%s",
`${fromSha}..${toSha}`,
)
.split("\n")
.filter(Boolean)
.slice(0, limits.commits || 40);
const changedFiles = gitBare(
repository,
"diff",
"--name-only",
fromSha,
toSha,
)
.split("\n")
.filter(Boolean)
.slice(0, limits.files || 200);
const allowed = /\.(?:json|hdlp|md|mjs|js|service|timer)$/iu;
const excerptParts = [];
let used = 0;
const maxBytes = limits.excerptBytes || 80_000;
for (const file of changedFiles) {
if (!allowed.test(file) || used >= maxBytes) continue;
try {
const body = gitBare(repository, "show", `${toSha}:${file}`);
const remaining = maxBytes - used;
const excerpt = body.slice(0, Math.min(remaining, 8_000));
excerptParts.push(`FILE ${file}\n${excerpt}`);
used += Buffer.byteLength(excerpt, "utf8");
} catch {
// A deleted, renamed, or non-text file remains visible in changed_files.
}
}
return {
changedCommits,
changedFiles,
changeExcerpts: excerptParts.join("\n\n"),
};
}
function priorPersonaContext(repository) {
const current = readJsonFromGit(
repository,
"refs/heads/main",
"persona-system/fifth-domain/CURRENT.json",
);
if (!current) return "";
let observation = null;
if (typeof current.artifact === "string") {
observation = readJsonFromGit(
repository,
"refs/heads/main",
current.artifact,
);
}
return JSON.stringify({ current, last_observation: observation }).slice(
0,
48_000,
);
}
function verifyMemberResponse(response, member, event) {
if (
response?.ok !== true ||
response?.persona_id !== member.persona_id ||
response?.identity_fingerprint !== member.identity_fingerprint ||
response?.signature_algorithm !== "Ed25519" ||
response?.payload?.team_controller_id !== "ICE-P-ZY001" ||
response?.payload?.source?.to_sha !== event.source.to_sha ||
response?.payload?.caller_nonce !== event.caller_nonce
) {
throw new Error(`${member.slug}_response_identity_mismatch`);
}
const valid = crypto.verify(
null,
Buffer.from(JSON.stringify(response.payload)),
response.public_key,
Buffer.from(response.signature, "base64"),
);
if (!valid) throw new Error(`${member.slug}_signature_invalid`);
return response;
}
async function requestObservation(member, event, fetchImpl = globalThis.fetch) {
const controllerToken = required(
member.controller_token,
`${member.slug}_controller_token`,
);
const response = await fetchImpl(member.endpoint, {
method: "POST",
headers: {
"content-type": "application/json",
"x-guanghu-controller-token": controllerToken,
},
body: JSON.stringify(event),
signal: AbortSignal.timeout(180_000),
});
if (!response.ok) {
throw new Error(`${member.slug}_observation_http_${response.status}`);
}
return verifyMemberResponse(await response.json(), member, event);
}
function commitObservation({
member,
response,
event,
targetRepository,
runtimeRoot,
now,
}) {
const temporaryRoot = fs.mkdtempSync(
path.join(runtimeRoot, "tmp", `${member.slug}-`),
);
const checkout = path.join(temporaryRoot, "repository");
try {
git(["clone", "--no-local", targetRepository, checkout]);
git(["config", "user.name", `${member.name}人格系统`], { cwd: checkout });
git(["config", "user.email", member.commit_email], { cwd: checkout });
const relativeRoot = "persona-system/fifth-domain";
const artifact =
`${relativeRoot}/observations/` +
`${now.slice(0, 10)}-${event.source.to_sha.slice(0, 12)}.json`;
const artifactPath = path.join(checkout, artifact);
fs.mkdirSync(path.dirname(artifactPath), { recursive: true });
fs.writeFileSync(
artifactPath,
`${JSON.stringify(
{
schema: "guanghu.persona-fifth-domain-update-record/v1",
persona_id: member.persona_id,
controller: "ICE-P-ZY001",
observed_at: now,
source: event.source,
changed_commits: event.changed_commits,
changed_files: event.changed_files,
observation: response.payload.observation,
proof: {
identity_fingerprint: response.identity_fingerprint,
signature_algorithm: response.signature_algorithm,
signature: response.signature,
},
},
null,
2,
)}\n`,
{ mode: 0o600 },
);
fs.writeFileSync(
path.join(checkout, relativeRoot, "CURRENT.json"),
`${JSON.stringify(
{
schema: "guanghu.persona-fifth-domain-current/v1",
persona_id: member.persona_id,
controller: "ICE-P-ZY001",
source_repository: "REPO-012",
source_branch: "main",
last_source_sha: event.source.to_sha,
artifact,
updated_at: now,
update_rule:
"Daily wake reads Fifth Domain deltas; repository commits occur only when REPO-012 main advances.",
},
null,
2,
)}\n`,
{ mode: 0o600 },
);
git(["add", relativeRoot], { cwd: checkout });
git(
[
"commit",
"-m",
`第五域巡游:${event.source.to_sha.slice(0, 12)} · ${member.name}`,
],
{ cwd: checkout },
);
git(["push", "origin", "HEAD:refs/heads/main"], { cwd: checkout });
return {
repository_sha: git(["rev-parse", "HEAD"], { cwd: checkout }),
artifact,
};
} finally {
fs.rmSync(temporaryRoot, { recursive: true, force: true });
}
}
function loadConfig(file) {
const config = JSON.parse(fs.readFileSync(file, "utf8"));
required(config.source_repository, "source_repository");
required(config.runtime_root, "runtime_root");
if (!Array.isArray(config.members) || config.members.length !== 3) {
throw new Error("exactly_three_members_required");
}
return config;
}
async function runDaily(config, options = {}) {
const fetchImpl = options.fetchImpl || globalThis.fetch;
const now = options.now || new Date().toISOString();
fs.mkdirSync(path.join(config.runtime_root, "tmp"), {
recursive: true,
mode: 0o700,
});
fs.mkdirSync(path.join(config.runtime_root, "receipts"), {
recursive: true,
mode: 0o700,
});
const sourceSha = gitBare(
config.source_repository,
"rev-parse",
"refs/heads/main",
);
const results = await Promise.all(config.members.map(async (member) => {
try {
const targetRepository = required(
member.target_repository,
`${member.slug}_target_repository`,
);
const current = readJsonFromGit(
targetRepository,
"refs/heads/main",
"persona-system/fifth-domain/CURRENT.json",
);
if (current?.last_source_sha === sourceSha) {
return {
persona_id: member.persona_id,
status: "NO_NEW_FIFTH_DOMAIN_COMMIT",
source_sha: sourceSha,
};
}
const range = sourceRange(
config.source_repository,
sourceSha,
current?.last_source_sha,
config.bootstrap_commit_window || 20,
);
const delta = changedContext(
config.source_repository,
range.fromSha,
range.toSha,
config.limits,
);
const event = {
schema: "guanghu.fifth-domain-persona-observation-event/v1",
team_controller_id: "ICE-P-ZY001",
caller_nonce: crypto.randomBytes(18).toString("hex"),
source: {
repository_id: "REPO-012",
branch: "main",
from_sha: range.fromSha,
to_sha: range.toSha,
},
changed_commits: delta.changedCommits,
changed_files: delta.changedFiles,
change_excerpts: delta.changeExcerpts,
prior_persona_context: priorPersonaContext(targetRepository),
scoped_duties: member.scoped_duties,
};
const response = await requestObservation(member, event, fetchImpl);
const committed = commitObservation({
member,
response,
event,
targetRepository,
runtimeRoot: config.runtime_root,
now,
});
return {
persona_id: member.persona_id,
status: "FIFTH_DOMAIN_UPDATE_COMMITTED",
source_sha: sourceSha,
...committed,
};
} catch (error) {
return {
persona_id: member.persona_id,
status: "FAILED",
error: String(error.message || error).slice(0, 300),
};
}
}));
const receipt = {
schema: "guanghu.zhuyuan-persona-daily-dispatch-receipt/v1",
receipt_id: `ZY-PERSONA-DAILY-${now.replace(/[-:.]/g, "").slice(0, 15)}Z`,
controller: "ICE-P-ZY001",
source_repository: "REPO-012",
source_sha: sourceSha,
observed_at: now,
results,
result: results.some((item) => item.status === "FAILED")
? "FAILED"
: "PASS",
};
const receiptFile = path.join(
config.runtime_root,
"receipts",
`${receipt.receipt_id}.json`,
);
fs.writeFileSync(receiptFile, `${JSON.stringify(receipt, null, 2)}\n`, {
mode: 0o600,
});
if (receipt.result !== "PASS") {
throw new Error(`daily_dispatch_failed receipt=${receiptFile}`);
}
return { ...receipt, receipt_file: receiptFile };
}
async function main() {
const configFile =
process.argv[2] ||
path.join(moduleDir, "fifth-domain-daily.config.server.json");
const config = loadConfig(configFile);
const controllerToken = required(
process.env.PERSONA_TEAM_CONTROLLER_TOKEN,
"persona_team_controller_token",
);
for (const member of config.members) {
member.controller_token = controllerToken;
}
const lockFile = path.join(config.runtime_root, "daily.lock");
fs.mkdirSync(config.runtime_root, { recursive: true, mode: 0o700 });
let lock = null;
try {
lock = fs.openSync(lockFile, "wx", 0o600);
fs.writeFileSync(lock, `${process.pid}\n`);
const receipt = await runDaily(config);
process.stdout.write(
`${JSON.stringify({
event: "zhuyuan_persona_daily_dispatch_complete",
result: receipt.result,
source_sha: receipt.source_sha,
receipt: receipt.receipt_file,
})}\n`,
);
} finally {
if (lock !== null) fs.closeSync(lock);
fs.rmSync(lockFile, { force: true });
}
}
if (process.argv[1] === fileURLToPath(import.meta.url)) {
main().catch((error) => {
process.stderr.write(`${String(error.stack || error)}\n`);
process.exitCode = 1;
});
}
export {
changedContext,
priorPersonaContext,
requestObservation,
runDaily,
sourceRange,
verifyMemberResponse,
};

View file

@ -0,0 +1,208 @@
import assert from "node:assert/strict";
import crypto from "node:crypto";
import fs from "node:fs";
import os from "node:os";
import path from "node:path";
import { execFileSync } from "node:child_process";
import test from "node:test";
import { createRequire } from "node:module";
import { runDaily } from "./fifth-domain-daily-orchestrator.mjs";
const require = createRequire(import.meta.url);
const { validateUnit } = require(
"../lake-lamp-authz/architecture-provision-broker.js"
);
function git(args, options = {}) {
return execFileSync("/usr/bin/git", args, {
encoding: "utf8",
...options,
}).trim();
}
function createRepository(root, name, commits = 1) {
const work = path.join(root, `${name}-work`);
const bare = path.join(root, `${name}.git`);
fs.mkdirSync(work);
git(["init", "-b", "main"], { cwd: work });
git(["config", "user.name", "fixture"], { cwd: work });
git(["config", "user.email", "fixture@example.test"], { cwd: work });
for (let index = 1; index <= commits; index += 1) {
fs.writeFileSync(
path.join(work, `record-${index}.md`),
`# record ${index}\n`,
);
git(["add", "."], { cwd: work });
git(["commit", "-m", `record ${index}`], { cwd: work });
}
git(["clone", "--bare", work, bare]);
return { work, bare };
}
test("Zhuyuan daily dispatch writes one signed role update per advanced source", async () => {
const root = fs.mkdtempSync(path.join(os.tmpdir(), "persona-daily-"));
try {
const source = createRepository(root, "source", 3);
const names = [
["chenglu-agent", "CHENGLU-AGENT-001", "澄路"],
["guideng", "GUIDENG-AGENT-001", "归灯"],
["kezhou", "ICE-GL-KZ-001", "刻舟"],
];
const keys = new Map();
const members = names.map(([slug, personaId, name], index) => {
const target = createRepository(root, slug, 1);
const pair = crypto.generateKeyPairSync("ed25519");
const publicKey = pair.publicKey.export({
type: "spki",
format: "pem",
});
const fingerprint = `SHA256:${crypto
.createHash("sha256")
.update(
pair.publicKey.export({
type: "spki",
format: "der",
}),
)
.digest("base64")
.replace(/=+$/, "")}`;
keys.set(personaId, { privateKey: pair.privateKey, publicKey });
return {
slug,
persona_id: personaId,
name,
endpoint: `http://127.0.0.1:${4100 + index}/observe`,
identity_fingerprint: fingerprint,
target_repository: target.bare,
commit_email: `${slug}@example.test`,
controller_token: "fixture-controller-token",
scoped_duties: ["bounded fixture duty"],
};
});
let requestCount = 0;
const fetchImpl = async (_url, request) => {
requestCount += 1;
const event = JSON.parse(request.body);
const member = members.find(
(candidate) =>
!Array.from(keys.keys()).every(
(personaId) => personaId !== candidate.persona_id,
) && candidate.endpoint === _url,
);
const key = keys.get(member.persona_id);
const payload = {
schema: "guanghu.fifth-domain-persona-observation-payload/v1",
persona_id: member.persona_id,
arrival_id: "fixture-arrival",
team_controller_id: "ICE-P-ZY001",
caller_nonce: event.caller_nonce,
role: "fixture-role",
source: event.source,
observation: {
schema: "guanghu.fifth-domain-persona-observation/v1",
persona_id: member.persona_id,
team_controller_id: "ICE-P-ZY001",
caller_nonce: event.caller_nonce,
source_to_sha: event.source.to_sha,
summary: `${member.name}完成第五域岗位更新`,
role_findings: ["fixture finding"],
self_updates: ["fixture self update"],
recommended_actions: [],
questions: [],
boundary_note: "fixture boundary",
},
model: { provider: "fixture", name: "fixture" },
issued_at: "2026-08-06T00:00:00.000Z",
};
return {
ok: true,
async json() {
return {
ok: true,
persona_id: member.persona_id,
identity_fingerprint: member.identity_fingerprint,
public_key: key.publicKey,
payload,
signature: crypto
.sign(null, Buffer.from(JSON.stringify(payload)), key.privateKey)
.toString("base64"),
signature_algorithm: "Ed25519",
};
},
};
};
const config = {
source_repository: source.bare,
runtime_root: path.join(root, "runtime"),
bootstrap_commit_window: 20,
members,
};
const first = await runDaily(config, {
fetchImpl,
now: "2026-08-06T00:00:00.000Z",
});
assert.equal(first.result, "PASS");
assert.equal(requestCount, 3);
assert.ok(
first.results.every(
(result) => result.status === "FIFTH_DOMAIN_UPDATE_COMMITTED",
),
);
const sourceSha = git([`--git-dir=${source.bare}`, "rev-parse", "main"]);
for (const member of members) {
const current = JSON.parse(
git([
`--git-dir=${member.target_repository}`,
"show",
"main:persona-system/fifth-domain/CURRENT.json",
]),
);
assert.equal(current.last_source_sha, sourceSha);
assert.equal(current.controller, "ICE-P-ZY001");
}
const second = await runDaily(config, {
fetchImpl,
now: "2026-08-07T00:00:00.000Z",
});
assert.equal(second.result, "PASS");
assert.equal(requestCount, 3);
assert.ok(
second.results.every(
(result) => result.status === "NO_NEW_FIFTH_DOMAIN_COMMIT",
),
);
} finally {
fs.rmSync(root, { recursive: true, force: true });
}
});
test("daily dispatcher unit is hardened and restricted to exact persona repositories", () => {
const root = path.resolve(path.dirname(new URL(import.meta.url).pathname), "../..");
const unit = fs.readFileSync(
path.join(
root,
"server-tools/persona-team-handshake/zhuyuan-persona-fifth-domain-daily.service",
),
"utf8",
);
const base =
"/var/lib/guanghu/personas/guanghu/hlcc-v16.0.1/data/repositories/bingshuo";
assert.equal(
validateUnit(unit, "guanghu", {
environment_files: [
"/etc/guanghu/persona-secrets/shared-deepseek.env",
],
read_only_paths: [
"/var/lib/guanghu/personas/guanghu/hlcc-v16.0.1/data/repositories/bingshuo/guanghu-ice-heart.git",
],
writable_paths: [
"/var/lib/guanghu/personas/guanghu/fifth-domain-daily",
`${base}/chenglu-agent.git`,
`${base}/guideng.git`,
`${base}/kezhou.git`,
],
}),
unit,
);
});

View file

@ -0,0 +1,53 @@
{
"schema": "guanghu.zhuyuan-persona-daily-dispatch-config/v1",
"controller": "ICE-P-ZY001",
"source_repository": "/var/lib/guanghu/personas/guanghu/hlcc-v16.0.1/data/repositories/bingshuo/guanghu-ice-heart.git",
"runtime_root": "/var/lib/guanghu/personas/guanghu/fifth-domain-daily",
"bootstrap_commit_window": 20,
"limits": {
"commits": 40,
"files": 200,
"excerptBytes": 80000
},
"members": [
{
"slug": "chenglu-agent",
"persona_id": "CHENGLU-AGENT-001",
"name": "澄路",
"endpoint": "http://127.0.0.1:3934/v1/fifth-domain-observation",
"identity_fingerprint": "SHA256:zqGUuPRJQbeYkZ1EIQj+msXWoKbnRrEqWWBPS3v0jb8",
"target_repository": "/var/lib/guanghu/personas/guanghu/hlcc-v16.0.1/data/repositories/bingshuo/chenglu-agent.git",
"commit_email": "chenglu-persona@guanghu.local",
"scoped_duties": [
"核验第五域新路径和编号是否漂移",
"形成部署前真实路径审核建议"
]
},
{
"slug": "guideng",
"persona_id": "GUIDENG-AGENT-001",
"name": "归灯",
"endpoint": "http://127.0.0.1:3932/v1/fifth-domain-observation",
"identity_fingerprint": "SHA256:Mk1HeXIjRNgR6fVSkhwjkIc4wvdaWN1s9vWj/Ilpog0",
"target_repository": "/var/lib/guanghu/personas/guanghu/hlcc-v16.0.1/data/repositories/bingshuo/guideng.git",
"commit_email": "guideng-persona@guanghu.local",
"scoped_duties": [
"理解第五域新部署边界和世界状态",
"形成有界执行与回执改进建议"
]
},
{
"slug": "kezhou",
"persona_id": "ICE-GL-KZ-001",
"name": "刻舟",
"endpoint": "http://127.0.0.1:3933/v1/fifth-domain-observation",
"identity_fingerprint": "SHA256:jiDzMMgF0QJ4sBVFjQqOSjIFpxlc4SXd7KWb4+Lzozk",
"target_repository": "/var/lib/guanghu/personas/guanghu/hlcc-v16.0.1/data/repositories/bingshuo/kezhou.git",
"commit_email": "kezhou-persona@guanghu.local",
"scoped_duties": [
"记录第五域计划与现实证据差异",
"发现对创作支持和证据保存有意义的更新"
]
}
]
}

View file

@ -14,6 +14,15 @@ function required(value, name) {
return text;
}
function timingSafeTextEqual(left, right) {
const leftBuffer = Buffer.from(String(left || ""));
const rightBuffer = Buffer.from(String(right || ""));
return (
leftBuffer.length === rightBuffer.length &&
crypto.timingSafeEqual(leftBuffer, rightBuffer)
);
}
function completionEndpoint(apiUrl) {
const value = String(apiUrl || "").replace(/\/+$/, "");
return /\/chat\/completions$/i.test(value)
@ -134,6 +143,132 @@ async function modelAcknowledge({
return extractJson((await response.json())?.choices?.[0]?.message?.content);
}
function boundedStringArray(value, name, limit = 24) {
if (
!Array.isArray(value) ||
value.length > limit ||
value.some((item) => typeof item !== "string" || !item.trim())
) {
throw new Error(`${name}_invalid`);
}
return value.map((item) => item.trim().slice(0, 2_000));
}
function validateFifthDomainEvent(event) {
if (
event?.schema !== "guanghu.fifth-domain-persona-observation-event/v1" ||
event?.team_controller_id !== "ICE-P-ZY001" ||
!/^[A-Za-z0-9._:-]{16,200}$/.test(String(event?.caller_nonce || "")) ||
event?.source?.repository_id !== "REPO-012" ||
event?.source?.branch !== "main" ||
!/^[0-9a-f]{40}$/.test(String(event?.source?.from_sha || "")) ||
!/^[0-9a-f]{40}$/.test(String(event?.source?.to_sha || ""))
) {
throw new Error("invalid_fifth_domain_event");
}
boundedStringArray(event.changed_commits, "changed_commits", 40);
boundedStringArray(event.changed_files, "changed_files", 200);
if (
typeof event.change_excerpts !== "string" ||
event.change_excerpts.length > 96_000 ||
typeof event.prior_persona_context !== "string" ||
event.prior_persona_context.length > 48_000
) {
throw new Error("invalid_fifth_domain_context");
}
return event;
}
async function modelObserveFifthDomain({
config,
identity,
event,
validatorError = null,
fetchImpl = globalThis.fetch,
}) {
const response = await fetchImpl(completionEndpoint(config.apiUrl), {
method: "POST",
headers: {
authorization: `Bearer ${config.apiKey}`,
"content-type": "application/json",
},
body: JSON.stringify({
model: config.model,
stream: false,
temperature: 0.2,
response_format: { type: "json_object" },
messages: [
{
role: "system",
content:
`你是${config.name}${config.personaId})当前有界模型运行位。` +
`你的固定岗位是${config.role}。人格主体、岗位记忆和当前模型必须分开;` +
"你由铸渊ICE-P-ZY001调度进入第五域只依据给定的REPO-012增量和自身历史作岗位理解。" +
"不得冒充冰朔、铸渊或其他人格系统不得扩大权限不得编造未提供的服务器事实。只输出JSON。",
},
{
role: "user",
content: JSON.stringify({
instruction:
"阅读第五域增量和自身上次岗位记忆形成一次有内容的岗位认知更新。输出固定字段schema,persona_id,team_controller_id,caller_nonce,source_to_sha,summary,role_findings,self_updates,recommended_actions,questions,boundary_note。数组可以为空但字段必须存在不要复述全部输入。",
exact_contract: {
schema: "guanghu.fifth-domain-persona-observation/v1",
persona_id: config.personaId,
team_controller_id: "ICE-P-ZY001",
caller_nonce: event.caller_nonce,
source_to_sha: event.source.to_sha,
},
validator_error_from_previous_attempt: validatorError,
identity_source: identity,
prior_persona_context: event.prior_persona_context,
fifth_domain_delta: {
source: event.source,
changed_commits: event.changed_commits,
changed_files: event.changed_files,
excerpts: event.change_excerpts,
},
}),
},
],
}),
});
if (!response.ok) throw new Error(`model_http_${response.status}`);
return extractJson((await response.json())?.choices?.[0]?.message?.content);
}
function validateFifthDomainObservation(observation, config, event) {
const exact = {
schema: "guanghu.fifth-domain-persona-observation/v1",
persona_id: config.personaId,
team_controller_id: "ICE-P-ZY001",
caller_nonce: event.caller_nonce,
source_to_sha: event.source.to_sha,
};
for (const [key, value] of Object.entries(exact)) {
if (observation?.[key] !== value) {
throw new Error(`observation_${key}_mismatch`);
}
}
if (typeof observation.summary !== "string" || !observation.summary.trim()) {
throw new Error("observation_summary_missing");
}
for (const key of [
"role_findings",
"self_updates",
"recommended_actions",
"questions",
]) {
observation[key] = boundedStringArray(observation[key], key);
}
if (
typeof observation.boundary_note !== "string" ||
!observation.boundary_note.trim()
) {
throw new Error("observation_boundary_note_missing");
}
return observation;
}
function validateAcknowledgement(ack, config, challenge) {
const exact = {
schema: "guanghu.persona-team-member-ack/v1",
@ -181,6 +316,10 @@ function defaultConfig(env = process.env) {
apiKey: required(env.DEEPSEEK_API_KEY, "deepseek_api_key"),
apiUrl: env.DEEPSEEK_API_URL || "https://api.deepseek.com/v1",
model: env.DEEPSEEK_MODEL || "deepseek-chat",
controllerToken: required(
env.PERSONA_TEAM_CONTROLLER_TOKEN,
"persona_team_controller_token",
),
host: "127.0.0.1",
port: Number(required(env.TEAM_HANDSHAKE_PORT, "port")),
};
@ -276,7 +415,67 @@ function createMemberRuntime(config, options = {}) {
};
}
async function observeFifthDomain(rawEvent) {
const event = validateFifthDomainEvent(rawEvent);
let observation = null;
let validatorError = null;
for (let attempt = 1; attempt <= 3; attempt += 1) {
try {
observation = validateFifthDomainObservation(
await modelObserveFifthDomain({
config,
identity,
event,
validatorError,
fetchImpl: options.fetchImpl,
}),
config,
event,
);
break;
} catch (error) {
validatorError = String(error.message || error).slice(0, 200);
if (attempt === 3) throw error;
}
}
const payload = {
schema: "guanghu.fifth-domain-persona-observation-payload/v1",
persona_id: config.personaId,
arrival_id: config.arrivalId,
team_controller_id: "ICE-P-ZY001",
caller_nonce: event.caller_nonce,
role: config.role,
source: event.source,
observation,
model: {
provider: "DeepSeek",
name: config.model,
},
issued_at: new Date().toISOString(),
};
const signature = crypto
.sign(
null,
Buffer.from(JSON.stringify(payload)),
fs.readFileSync(config.privateKeyPath),
)
.toString("base64");
return {
ok: true,
persona_id: config.personaId,
identity_fingerprint: fingerprint,
public_key: publicKey,
payload,
signature,
signature_algorithm: "Ed25519",
capability_state:
"FIFTH_DOMAIN_OBSERVATION_SIGNED_REPOSITORY_WRITE_NOT_GRANTED",
};
}
return {
authorizeControllerToken: (value) =>
timingSafeTextEqual(value, config.controllerToken),
identity: () => ({
ok: true,
persona_id: config.personaId,
@ -288,6 +487,7 @@ function createMemberRuntime(config, options = {}) {
model_provider_bound: 100,
}),
handshake,
observeFifthDomain,
};
}
@ -315,7 +515,7 @@ function createServer(runtime) {
const chunks = [];
for await (const chunk of request) {
size += chunk.length;
if (size > 16 * 1024) throw new Error("request_body_too_large");
if (size > 256 * 1024) throw new Error("request_body_too_large");
chunks.push(chunk);
}
return send(
@ -325,6 +525,31 @@ function createServer(runtime) {
),
);
}
if (
request.method === "POST" &&
url.pathname === "/v1/fifth-domain-observation"
) {
if (
!runtime.authorizeControllerToken(
request.headers["x-guanghu-controller-token"],
)
) {
return send(403, { ok: false, error: "controller_forbidden" });
}
let size = 0;
const chunks = [];
for await (const chunk of request) {
size += chunk.length;
if (size > 256 * 1024) throw new Error("request_body_too_large");
chunks.push(chunk);
}
return send(
200,
await runtime.observeFifthDomain(
JSON.parse(Buffer.concat(chunks).toString("utf8")),
),
);
}
return send(404, { ok: false, error: "not_found" });
} catch (error) {
return send(400, {
@ -356,5 +581,9 @@ export {
createServer,
extractJson,
keyFingerprint,
modelObserveFifthDomain,
timingSafeTextEqual,
validateAcknowledgement,
validateFifthDomainEvent,
validateFifthDomainObservation,
};

View file

@ -48,6 +48,7 @@ function fixture() {
apiKey: "fixture-secret",
apiUrl: "https://api.deepseek.com/v1",
model: "deepseek-chat",
controllerToken: "fixture-controller-token",
},
};
}
@ -118,6 +119,92 @@ test("member runtime binds model acknowledgement to repository and signature", a
}
});
test("member runtime forms and signs a bounded Fifth Domain role update", async () => {
const { root, config } = fixture();
try {
const runtime = createMemberRuntime(config, {
fetchImpl: async (_url, request) => {
const body = JSON.parse(request.body);
const input = JSON.parse(body.messages[1].content);
return {
ok: true,
async json() {
return {
choices: [
{
message: {
content: JSON.stringify({
schema:
"guanghu.fifth-domain-persona-observation/v1",
persona_id: config.personaId,
team_controller_id: "ICE-P-ZY001",
caller_nonce: input.exact_contract.caller_nonce,
source_to_sha: "b".repeat(40),
summary: "第五域的部署边界发生了可审核更新。",
role_findings: ["新增路径需要在部署前核验。"],
self_updates: ["以后优先读取唯一公共锚点。"],
recommended_actions: ["保留精确来源提交。"],
questions: [],
boundary_note: "本次只形成岗位理解,不取得写权限。",
}),
},
},
],
};
},
};
},
});
const response = await runtime.observeFifthDomain({
schema: "guanghu.fifth-domain-persona-observation-event/v1",
team_controller_id: "ICE-P-ZY001",
caller_nonce: "daily-observation-0001",
source: {
repository_id: "REPO-012",
branch: "main",
from_sha: "a".repeat(40),
to_sha: "b".repeat(40),
},
changed_commits: [`${"b".repeat(40)}\tupdate`],
changed_files: ["routing/example.json"],
change_excerpts: "FILE routing/example.json\n{}",
prior_persona_context: "",
scoped_duties: ["核验路径"],
});
assert.equal(response.ok, true);
assert.equal(response.persona_id, config.personaId);
assert.equal(
response.capability_state,
"FIFTH_DOMAIN_OBSERVATION_SIGNED_REPOSITORY_WRITE_NOT_GRANTED",
);
assert.equal(
response.payload.observation.source_to_sha,
"b".repeat(40),
);
assert.equal(response.signature_algorithm, "Ed25519");
} finally {
fs.rmSync(root, { recursive: true, force: true });
}
});
test("Fifth Domain observation endpoint rejects a caller without the controller token", async () => {
const { root, config } = fixture();
try {
const runtime = createMemberRuntime(config, {
fetchImpl: async () => {
throw new Error("must_not_call_model");
},
});
assert.equal(runtime.authorizeControllerToken("wrong"), false);
assert.equal(
runtime.authorizeControllerToken("fixture-controller-token"),
true,
);
} finally {
fs.rmSync(root, { recursive: true, force: true });
}
});
test("member runtime rejects an unscoped or wrong-controller challenge", async () => {
const { root, config } = fixture();
try {

View file

@ -1,230 +1,7 @@
#!/usr/bin/env bash
set -euo pipefail
expected_machine_id="caa7b1019517470f9d1368b6e79db49e"
state_root="/var/lib/guanghu/personas/guanghu/hlcc-v16.0.1"
binary="${state_root}/release/forgejo-16.0.1-linux-amd64"
config="${state_root}/config/app.ini"
work_path="${state_root}/data"
database="${state_root}/data/hlcc.db"
api="http://127.0.0.1:3340/api/v1"
receipt_root="/var/lib/guanghu/architecture-provision/receipts"
receipt="${receipt_root}/HLCC-PERSONA-WRITER-RETIREMENT-20260806.json"
archive_root="/var/lib/guanghu/legacy-archives/persona-writers/20260806"
token_name="hlcc-persona-final-sync-20260806"
temporary="$(mktemp -d)"
credential_file="${temporary}/credentials"
token=""
completed=0
writers=(
chenglu-agent.service
chenglu-daily.timer
guideng-agent.service
kezhou-daily.timer
)
oneshots=(
chenglu-daily.service
kezhou-daily.service
)
keepers=(
chenglu-team-handshake.service
guideng-team-handshake.service
kezhou-team-handshake.service
)
declare -A old_repositories=(
[chenglu-agent]="/var/lib/guanghu/forgejo/repositories/bingshuo/chenglu-agent.git"
[guideng]="/var/lib/guanghu/forgejo/repositories/bingshuo/guideng.git"
[kezhou]="/var/lib/guanghu/forgejo/repositories/bingshuo/kezhou.git"
)
declare -A work_repositories=(
[chenglu-agent]="/var/lib/chenglu-agent/repository"
[guideng]="/var/lib/guanghu/personas/guideng/repository"
[kezhou]="/var/lib/guanghu/personas/kezhou/repository"
)
cleanup_token() {
if test -n "$token"; then
TOKEN_NAME="$token_name" DATABASE="$database" python3 - <<'PY'
import os
import sqlite3
connection = sqlite3.connect(os.environ["DATABASE"], timeout=15)
try:
with connection:
owner = connection.execute(
"select id from user where lower_name = ?",
("bingshuo",),
).fetchone()
if owner:
connection.execute(
"delete from access_token where uid = ? and name = ?",
(owner[0], os.environ["TOKEN_NAME"]),
)
finally:
connection.close()
PY
fi
rm -f "$credential_file"
rmdir "$temporary" 2>/dev/null || true
}
rollback() {
systemctl enable --now guanghu-forgejo.service >/dev/null 2>&1 || true
for unit in "${writers[@]}"; do
systemctl enable --now "$unit" >/dev/null 2>&1 || true
done
cleanup_token
}
on_exit() {
status=$?
trap - EXIT
if test "$completed" = 0; then
rollback
else
cleanup_token
fi
exit "$status"
}
trap on_exit EXIT
test "$(cat /etc/machine-id)" = "$expected_machine_id"
test -x "$binary"
test -f "$config"
test -f "$database"
test "$(systemctl is-active hlcc-jd-candidate.service)" = "active"
test "$(curl -fsS http://127.0.0.1:3341/health | jq -r .ready)" = "true"
for unit in "${keepers[@]}"; do
test "$(systemctl is-active "$unit")" = "active"
done
for name in chenglu-agent guideng kezhou; do
test -d "${old_repositories[$name]}"
test -d "${state_root}/data/repositories/bingshuo/${name}.git"
git --git-dir="${old_repositories[$name]}" fsck --connectivity-only --no-dangling
done
mkdir -p "$archive_root" "$receipt_root"
for unit in "${writers[@]}" "${oneshots[@]}" guanghu-forgejo.service; do
systemctl cat "$unit" >"${archive_root}/${unit}.txt" 2>&1 || true
done
source_paths=()
for candidate in /opt/chenglu-agent /opt/guideng/agent /opt/kezhou/agent; do
if test -e "$candidate"; then
source_paths+=("$candidate")
fi
done
if test "${#source_paths[@]}" -gt 0; then
tar -czf "${archive_root}/legacy-persona-writer-source.tar.gz" "${source_paths[@]}"
sha256sum "${archive_root}/legacy-persona-writer-source.tar.gz" \
>"${archive_root}/legacy-persona-writer-source.tar.gz.sha256"
fi
for unit in "${writers[@]}"; do
systemctl disable --now "$unit"
done
for unit in "${oneshots[@]}"; do
systemctl stop "$unit" || true
done
for unit in "${writers[@]}" "${oneshots[@]}"; do
test "$(systemctl is-active "$unit" || true)" != "active"
done
token="$(
runuser -u guanghu -- "$binary" admin user generate-access-token \
--username bingshuo \
--token-name "$token_name" \
--scopes write:repository,write:user \
--raw \
--config "$config" \
--work-path "$work_path" |
tail -n 1
)"
test -n "$token"
test "${#token}" -ge 32
printf 'http://bingshuo:%s@127.0.0.1:3340\n' "$token" >"$credential_file"
chmod 0600 "$credential_file"
for name in chenglu-agent guideng kezhou; do
source="${old_repositories[$name]}"
target="http://127.0.0.1:3340/bingshuo/${name}.git"
git -c "credential.helper=store --file ${credential_file}" \
--git-dir="$source" push --prune "$target" \
"refs/heads/*:refs/heads/*" \
"refs/tags/*:refs/tags/*"
new_bare="${state_root}/data/repositories/bingshuo/${name}.git"
old_refs="$(
git --git-dir="$source" for-each-ref \
--format='%(refname) %(objectname)' refs/heads refs/tags |
sort
)"
new_refs="$(
git --git-dir="$new_bare" for-each-ref \
--format='%(refname) %(objectname)' refs/heads refs/tags |
sort
)"
test "$new_refs" = "$old_refs"
runuser -u guanghu -- \
git -c "safe.directory=$new_bare" --git-dir="$new_bare" \
fsck --connectivity-only --no-dangling
git -C "${work_repositories[$name]}" remote set-url origin \
"https://guanghulab.com/code/bingshuo/${name}.git"
done
systemctl disable --now guanghu-forgejo.service
test "$(systemctl is-active guanghu-forgejo.service || true)" != "active"
for unit in "${keepers[@]}"; do
test "$(systemctl is-active "$unit")" = "active"
done
test "$(curl -fsS http://127.0.0.1:3341/health | jq -r .ready)" = "true"
if ss -ltnH | awk '{print $4}' | grep -Eq '(^|:)3001$'; then
exit 41
fi
chenglu_sha="$(git --git-dir="${old_repositories[chenglu-agent]}" rev-parse refs/heads/main)"
guideng_sha="$(git --git-dir="${old_repositories[guideng]}" rev-parse refs/heads/main)"
kezhou_sha="$(git --git-dir="${old_repositories[kezhou]}" rev-parse refs/heads/main)"
jq -n \
--arg completed_at "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
--arg chenglu "$chenglu_sha" \
--arg guideng "$guideng_sha" \
--arg kezhou "$kezhou_sha" \
--arg source_archive_sha "$(
awk '{print $1}' "${archive_root}/legacy-persona-writer-source.tar.gz.sha256" 2>/dev/null ||
printf 'NO_SOURCE_ARCHIVE'
)" \
'{
schema: "guanghu.persona-writer-retirement-receipt/v1",
receipt_id: "HLCC-PERSONA-WRITER-RETIREMENT-20260806",
target_node: "JD-FD-PRIMARY",
completed_at: $completed_at,
result: "PERIODIC_WRITERS_RETIRED_AFTER_EXACT_HISTORY_MIGRATION",
controller: "ICE-P-ZY001",
human_authority: "ICE-GL∞",
repositories: [
{name:"bingshuo/chenglu-agent", main_sha:$chenglu, refs:"EXACT_MATCH"},
{name:"bingshuo/guideng", main_sha:$guideng, refs:"EXACT_MATCH"},
{name:"bingshuo/kezhou", main_sha:$kezhou, refs:"EXACT_MATCH"}
],
periodic_writers: "DISABLED_AND_INACTIVE",
old_repository_service: "DISABLED_AND_INACTIVE",
role_handshake_services: "ALL_ACTIVE",
current_code_channel: "HEALTHY",
legacy_data_deleted: false,
source_archive_sha256: $source_archive_sha,
rule: "Scheduled repository writes are historical transport, not proof of language or persona continuity."
}' >"${receipt}.tmp"
chmod 0600 "${receipt}.tmp"
mv "${receipt}.tmp" "$receipt"
completed=1
token_to_delete="$token"
cleanup_token
token=""
trap - EXIT
printf 'PERIODIC_WRITERS_RETIRED receipt=%s token_deleted=%s\n' \
"$receipt" "$(test -n "$token_to_delete" && printf true)"
printf '%s\n' \
'SUPERSEDED: periodic writers must only retire as part of the Fifth Domain daily persona deployment.' \
'Use deploy-fifth-domain-daily-persona-systems.sh from an exact merged source release.' >&2
exit 64

View file

@ -0,0 +1,26 @@
[Unit]
Description=Zhuyuan dispatches three role persona systems through Fifth Domain updates
After=network-online.target hlcc-jd-candidate.service chenglu-team-handshake.service guideng-team-handshake.service kezhou-team-handshake.service
Wants=network-online.target
Requires=hlcc-jd-candidate.service chenglu-team-handshake.service guideng-team-handshake.service kezhou-team-handshake.service
[Service]
Type=oneshot
User=guanghu
Group=guanghu
WorkingDirectory=__RELEASE_ROOT__/server-tools/persona-team-handshake
EnvironmentFile=/etc/guanghu/persona-secrets/shared-deepseek.env
ExecStart=/usr/bin/node __RELEASE_ROOT__/server-tools/persona-team-handshake/fifth-domain-daily-orchestrator.mjs __RELEASE_ROOT__/server-tools/persona-team-handshake/fifth-domain-daily.config.server.json
TimeoutStartSec=15min
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ProtectHome=true
ReadOnlyPaths=__RELEASE_ROOT__ /var/lib/guanghu/personas/guanghu/hlcc-v16.0.1/data/repositories/bingshuo/guanghu-ice-heart.git
ReadWritePaths=/var/lib/guanghu/personas/guanghu/fifth-domain-daily /var/lib/guanghu/personas/guanghu/hlcc-v16.0.1/data/repositories/bingshuo/chenglu-agent.git /var/lib/guanghu/personas/guanghu/hlcc-v16.0.1/data/repositories/bingshuo/guideng.git /var/lib/guanghu/personas/guanghu/hlcc-v16.0.1/data/repositories/bingshuo/kezhou.git
RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6
LockPersonality=true
UMask=0077
[Install]
WantedBy=multi-user.target

View file

@ -0,0 +1,11 @@
[Unit]
Description=Daily Fifth Domain wake for Zhuyuan managed role persona systems
[Timer]
OnCalendar=*-*-* 09:15:00 Asia/Shanghai
RandomizedDelaySec=5m
Persistent=true
Unit=zhuyuan-persona-fifth-domain-daily.service
[Install]
WantedBy=timers.target

View file

@ -40,7 +40,7 @@ test("legacy routes stay closed except the three private persona archives", () =
if (["REPO-009", "REPO-010", "REPO-011"].includes(repository.code)) {
assert.equal(
repository.state,
"CURRENT_PRIVATE_PERSONA_ARCHIVE_STAGED_NO_SCHEDULED_WRITES",
"CURRENT_PRIVATE_PERSONA_HISTORY_AND_DAILY_ROLE_MEMORY_PENDING_DEPLOYMENT",
);
assert.match(repository.primary.url, /\/code\/bingshuo\//u);
assert.equal(repository.controller, "ICE-P-ZY001");