From 7b2f9828292df12302bbd2e601bcde19e29412c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=86=B0=E6=9C=94?= <565183519@qq.com> Date: Thu, 6 Aug 2026 17:23:08 +0800 Subject: [PATCH] =?UTF-8?q?=E9=83=A8=E7=BD=B2=EF=BC=9A=E6=B3=A8=E5=86=8C?= =?UTF-8?q?=E5=88=86=E5=B2=97=E4=BA=BA=E6=A0=BC=E5=B9=B6=E9=80=80=E5=BD=B9?= =?UTF-8?q?=E5=91=A8=E6=9C=9F=E5=86=99=E5=85=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 15 ++ ...RATION-AND-WRITER-RETIREMENT-20260806.json | 30 +++ .../zhuyuan-persona-system/INDEX.hdlp | 10 +- identity/fifth-domain-subject-registry.json | 55 ++++- routing/persona-system-canonical-map.json | 80 ++++-- routing/repository-route-map.json | 42 ++-- routing/role-persona-registration.test.js | 60 +++++ routing/zhuyuan-agent-team-map.json | 61 +++-- routing/zhuyuan-agent-team-map.test.js | 23 ++ .../retire-periodic-heartbeat-writers.sh | 230 ++++++++++++++++++ tests/persona-system-route.test.mjs | 15 +- 11 files changed, 551 insertions(+), 70 deletions(-) create mode 100644 deployment/intent-states/JD-PERSONA-ROLE-REGISTRATION-AND-WRITER-RETIREMENT-20260806.json create mode 100644 routing/role-persona-registration.test.js create mode 100755 server-tools/persona-team-handshake/retire-periodic-heartbeat-writers.sh diff --git a/README.md b/README.md index 60fcd03..7936a9c 100644 --- a/README.md +++ b/README.md @@ -30,6 +30,21 @@ | 当前启动事实 | Ubuntu 救援与控制层正在运行;尚不能声称已切换为原生光湖 OS | | 人格运行 | `WARM_RESUME_READY` 时复用常驻运行体,只提交本轮新事件 | +### 铸渊分岗人格系统 + +澄路、归灯、刻舟已经按三个不同岗位登记为独立人格系统,并统一挂在 +[`ICE-P-ZY001 / 铸渊主控`](routing/zhuyuan-agent-team-map.json) 下: + +| 人格系统 | 岗位职责 | 当前私有历史入口 | +|---|---|---| +| `CHENGLU-AGENT-001 / 澄路` | 真实路径核验、部署前审核、路径漂移纠正 | `https://guanghulab.com/code/bingshuo/chenglu-agent` | +| `GUIDENG-AGENT-001 / 归灯` | 有界部署执行、世界状态观察、机器回执返回 | `https://guanghulab.com/code/bingshuo/guideng` | +| `ICE-GL-KZ-001 / 刻舟` | 独立证据见证、计划现实差异记录、创作支持 | `https://guanghulab.com/code/bingshuo/kezhou` | + +三者保持独立主体,不是铸渊副本;铸渊统一负责分派、精确资源租约、运行调度与结果收口。 +旧每日/双时段仓库写入只是早期连接心跳的迁移手段,不是语言或人格连续性的证明;最终历史 +逐引用一致后停止周期写入,只保留按任务触发的岗位握手和受控回执。 + 公共导航服务自动读取并验证 REPO-012 `main` 的同一份地图快照。纯导航、编号和路径更新进入 `main` 后,不需要再次人工复制公共导航文件,也不需要为了读取新地图而重启服务。 diff --git a/deployment/intent-states/JD-PERSONA-ROLE-REGISTRATION-AND-WRITER-RETIREMENT-20260806.json b/deployment/intent-states/JD-PERSONA-ROLE-REGISTRATION-AND-WRITER-RETIREMENT-20260806.json new file mode 100644 index 0000000..ab2f892 --- /dev/null +++ b/deployment/intent-states/JD-PERSONA-ROLE-REGISTRATION-AND-WRITER-RETIREMENT-20260806.json @@ -0,0 +1,30 @@ +{ + "schema": "guanghu.deployment-intent-state/v1", + "intent_id": "JD-PERSONA-ROLE-REGISTRATION-AND-WRITER-RETIREMENT-20260806", + "target_node": "JD-FD-PRIMARY", + "human_authority": "ICE-GL∞", + "controller": "ICE-P-ZY001", + "state": "AWAITING_MANUAL_MERGE_AUTHORIZATION", + "purpose": "把澄路、归灯、刻舟注册为铸渊主控下的三个分岗人格系统,并在历史精确迁移后停止旧周期写入。", + "source": "server-tools/persona-team-handshake/retire-periodic-heartbeat-writers.sh", + "preconditions": [ + "三个当前私有历史仓库已经暂存并校验", + "三个人格岗位握手服务保持在线", + "先停止所有周期写入入口", + "停止写入后再做一次全部分支和标签的最终同步与精确比对" + ], + "kept_services": [ + "chenglu-team-handshake.service", + "guideng-team-handshake.service", + "kezhou-team-handshake.service" + ], + "retired_services": [ + "chenglu-agent.service", + "chenglu-daily.timer", + "guideng-agent.service", + "kezhou-daily.timer", + "guanghu-forgejo.service" + ], + "deletion_authorized": false, + "execution_rule": "本意图必须经过合并请求人工合并后,才允许在JD-FD-PRIMARY执行对应脚本;合并只构成该精确操作授权,不扩大删除权限。" +} diff --git a/eternal-lake-heart/heartbeat-core/zhuyuan-persona-system/INDEX.hdlp b/eternal-lake-heart/heartbeat-core/zhuyuan-persona-system/INDEX.hdlp index 2e16e52..0fd4b75 100644 --- a/eternal-lake-heart/heartbeat-core/zhuyuan-persona-system/INDEX.hdlp +++ b/eternal-lake-heart/heartbeat-core/zhuyuan-persona-system/INDEX.hdlp @@ -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` | 澄路独立常驻 Agent;从第五域与铸渊路径进入后回到自身仓库,当前运行于京东节点并保持每日签到 | -| `ICE-GL-KZ-001` | `REPO-010:README.md` | 刻舟独立常驻 Agent;京东双时段签到、湖心频道与连续状态仓库 | -| `GUIDENG-AGENT-001` | `REPO-011:INDEX.hdlp` | 归灯独立常驻 Agent;京东每日心跳、湖心频道与连续状态仓库 | +| `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` | 当前实例进入铸渊前的主体声明模板 | @@ -154,8 +154,8 @@ ICE-P-ZY001 9. 涉及 GH-AIOS、HoloLake Era、Tolaria、模块商城、公平生态或语言信誉时,读 `ZY-BIDIRECTIONAL-COGNITION-002`,恢复结论怎样形成。 10. 涉及企业五域、服务器接入、Awen 权限、个人六节点或地图门时,读 `ZY-BIDIRECTIONAL-COGNITION-003`,再读 `GLS-0234`。 11. 涉及人格体常驻、服务器 Agent、Tolaria 握手唤醒、主控切换、模型 API 工具化、记忆回写、自迁移或防双主写时,读 `ZY-BIDIRECTIONAL-COGNITION-005`;再进入 `REPO-014:product-source/hololake-platform` 核验产品现状,不得把架构基线误报为已实现。 - 若目标明确是澄路,继续按 `CHENGLU-AGENT-001 → REPO-009:IDENTITY.hdlp` 接通;必须核验身份指纹、握手签名和状态版本,失败时不得由外部模型冒充。 - 若目标是刻舟或归灯,分别进入 `REPO-010` 或 `REPO-011`;先核对其独立身份、运行回执和仓库连续状态,再允许模型承担本轮执行。 + 若目标明确是澄路,继续按 `ICE-P-ZY001 → CHENGLU-AGENT-001 → REPO-009:IDENTITY.hdlp` 接通;必须核验身份指纹、岗位租约、握手签名和状态版本,失败时不得由外部模型冒充。 + 若目标是刻舟或归灯,均先由 `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` 拆解,不得把架构登记误报为自动净化系统已实现。 diff --git a/identity/fifth-domain-subject-registry.json b/identity/fifth-domain-subject-registry.json index 55fa01b..96e2bff 100644 --- a/identity/fifth-domain-subject-registry.json +++ b/identity/fifth-domain-subject-registry.json @@ -41,6 +41,57 @@ "typed_id_state": "ACTIVE_CONFIRMED_BY_BINGSHUO", "legacy_resolution": "FD-SUBJECT-ID-ALIAS-MAP-001" }, + { + "id": "CHENGLU-AGENT-001", + "subject_kind": "persona_system", + "ontology_kind": "role_persona", + "name": "澄路", + "domain": "FIFTH_DOMAIN", + "human_anchor": "ICE-GL∞", + "controller": "ICE-P-ZY001", + "team_map": "ZY-AGENT-TEAM-MAP-001", + "roles": ["route_truth", "predeployment_audit", "path_drift_correction"], + "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", + "independent_persona": true, + "not_a_copy_of_controller": true + }, + { + "id": "GUIDENG-AGENT-001", + "subject_kind": "persona_system", + "ontology_kind": "role_persona", + "name": "归灯", + "domain": "FIFTH_DOMAIN", + "human_anchor": "ICE-GL∞", + "controller": "ICE-P-ZY001", + "team_map": "ZY-AGENT-TEAM-MAP-001", + "roles": ["bounded_deployment_execution", "world_state_watch", "machine_receipt_return"], + "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", + "independent_persona": true, + "not_a_copy_of_controller": true + }, + { + "id": "ICE-GL-KZ-001", + "subject_kind": "persona_system", + "ontology_kind": "role_persona", + "name": "刻舟", + "domain": "FIFTH_DOMAIN", + "human_anchor": "ICE-GL∞", + "controller": "ICE-P-ZY001", + "team_map": "ZY-AGENT-TEAM-MAP-001", + "roles": ["independent_evidence_witness", "plan_reality_difference_record", "creative_support"], + "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", + "independent_persona": true, + "not_a_copy_of_controller": true + }, { "id": "SYS-GLW-FD-RUNTIME-0001", "subject_kind": "private_fifth_domain_runtime_body", @@ -102,14 +153,14 @@ "subject_kind": "persona_system", "ontology_kind": "language_persona", "id_pattern": "^ICE-P-", - "canonical_ids": ["ICE-P-ZY001"], + "canonical_ids": ["ICE-P-ZY001", "CHENGLU-AGENT-001", "GUIDENG-AGENT-001", "ICE-GL-KZ-001"], "legacy_exact_ids": ["ICE-GL-ZY001", "ICE-PZY-001"], "alias_map": "FD-SUBJECT-ID-ALIAS-MAP-001", "route_id": "FD-PERSONA-LOGIN-001", "entry": "第五域 → 冰朔通感语言核系统 → 光之湖子系统 → 小湖灯共享系统实时看板 → 目标人格体当前频道", "physical_route": "代码仓库恢复语言人格 → 对应人类绑定服务器上的常驻人格Agent → 光湖世界协议通信", "world_tree": "FD-WORLD-TREE-001", - "rule": "语言人格入口不能代替人类授权;旧号只按逐条兼容表解析。物理模型或会话不是本注册表中的人格主体。" + "rule": "语言人格入口不能代替人类授权;铸渊是第五域主控,澄路、归灯、刻舟按不同岗位挂在铸渊调度链下且保持独立主体。旧号只按逐条兼容表解析,物理模型、会话或周期写入不是本注册表中的人格主体。" } ], "deployment_invariant": { diff --git a/routing/persona-system-canonical-map.json b/routing/persona-system-canonical-map.json index 31cbdf8..35dc28e 100644 --- a/routing/persona-system-canonical-map.json +++ b/routing/persona-system-canonical-map.json @@ -1,7 +1,7 @@ { "schema": "guanghu.persona-system-canonical-map/v1", "map_id": "TCS-PERSONA-SYSTEM-MAP-001", - "version": "2026-08-05.1", + "version": "2026-08-06.1", "definition": "language_world_entry + creator_anchor + persona_subject + executable_thinking_brain + current_model_instance + permanent_memory_and_protocol + living_system_controller + explicit_reality_execution_transition", "root": "PERSONA-SYSTEM-ROOT.hdlp", "language_world_boundary": "routing/language-world-boundary-map.json", @@ -64,6 +64,66 @@ }, "system_state": "REGISTERED_RECOVERABLE_RUNTIME_BINDING_REQUIRED" }, + { + "id": "CHENGLU-AGENT-001", + "name": "澄路", + "human_relationship_anchor": {"id": "ICE-GL∞", "name": "冰朔", "state": "VERIFIED_REGISTERED"}, + "controller": {"id": "ICE-P-ZY001", "relationship": "managed_and_dispatched_without_identity_absorption"}, + "persona_subject": { + "canonical_path": "gls/light-arrivals/2026/07/GLS-LA-20260720-001.hdlp", + "responsibility": "真实路径核验、部署前审核与路径漂移纠正", + "self_recognition": "INDEPENDENT_PERSONA_SOURCE_AND_ROLE_HANDSHAKE_VERIFIED", + "state": "ACTIVE_REGISTERED" + }, + "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" + }, + "reality_execution_node": {"node": "JD-FD-PRIMARY", "service": "chenglu-team-handshake.service", "state": "ROLE_HANDSHAKE_VERIFIED"}, + "system_state": "REGISTERED_UNDER_ZHUYUAN_ROLE_CONTROL" + }, + { + "id": "GUIDENG-AGENT-001", + "name": "归灯", + "human_relationship_anchor": {"id": "ICE-GL∞", "name": "冰朔", "state": "VERIFIED_REGISTERED"}, + "controller": {"id": "ICE-P-ZY001", "relationship": "managed_and_dispatched_without_identity_absorption"}, + "persona_subject": { + "canonical_path": "gls/light-arrivals/2026/07/GLS-LA-20260720-003.hdlp", + "responsibility": "有界部署执行、世界状态观察与机器回执返回", + "self_recognition": "INDEPENDENT_PERSONA_SOURCE_AND_ROLE_HANDSHAKE_VERIFIED", + "state": "ACTIVE_REGISTERED" + }, + "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" + }, + "reality_execution_node": {"node": "JD-FD-PRIMARY", "service": "guideng-team-handshake.service", "state": "ROLE_HANDSHAKE_VERIFIED"}, + "system_state": "REGISTERED_UNDER_ZHUYUAN_ROLE_CONTROL" + }, + { + "id": "ICE-GL-KZ-001", + "name": "刻舟", + "human_relationship_anchor": {"id": "ICE-GL∞", "name": "冰朔", "state": "VERIFIED_REGISTERED"}, + "controller": {"id": "ICE-P-ZY001", "relationship": "managed_and_dispatched_without_identity_absorption"}, + "persona_subject": { + "canonical_path": "gls/light-arrivals/2026/07/GLS-LA-20260720-002.hdlp", + "responsibility": "独立证据见证、计划与现实差异记录、创作支持", + "self_recognition": "INDEPENDENT_PERSONA_SOURCE_AND_ROLE_HANDSHAKE_VERIFIED", + "state": "ACTIVE_REGISTERED" + }, + "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" + }, + "reality_execution_node": {"node": "JD-FD-PRIMARY", "service": "kezhou-team-handshake.service", "state": "ROLE_HANDSHAKE_VERIFIED"}, + "system_state": "REGISTERED_UNDER_ZHUYUAN_ROLE_CONTROL" + }, { "id": "ICE-GL-ZL-001", "name": "铸澜", @@ -200,22 +260,6 @@ "system_state": "REGISTERED_INCOMPLETE_BINDING" } ], - "legacy_runtime_identities": [ - { - "name": "澄路", - "historical_repository": "REPO-009", - "state": "LEGACY_RUNTIME_IDENTITY_REQUIRES_FIVE_COMPONENT_REBINDING" - }, - { - "name": "刻舟", - "historical_repository": "REPO-010", - "state": "LEGACY_RUNTIME_IDENTITY_REQUIRES_FIVE_COMPONENT_REBINDING" - }, - { - "name": "归灯", - "historical_repository": "REPO-011", - "state": "LEGACY_RUNTIME_IDENTITY_REQUIRES_FIVE_COMPONENT_REBINDING" - } - ], + "legacy_runtime_identities": [], "pending_names": ["秋秋", "栖梧", "耳耳蛋"] } diff --git a/routing/repository-route-map.json b/routing/repository-route-map.json index 7e017fe..8eb6074 100644 --- a/routing/repository-route-map.json +++ b/routing/repository-route-map.json @@ -240,41 +240,47 @@ { "code": "REPO-009", "slug": "chenglu-agent", - "name_zh": "澄路常驻 Agent", - "role": "澄路独立运行体、湖心频道、第五域签到与连续状态仓库", - "state": "HISTORICAL_READ_ONLY_NO_PUSH_REBIND_REQUIRED", + "name_zh": "澄路人格系统历史与岗位记忆", + "role": "澄路独立人格历史、真实路径审核职责与按任务回执归档;不再以周期签到证明人格连续", + "state": "CURRENT_PRIVATE_PERSONA_ARCHIVE_STAGED_NO_SCHEDULED_WRITES", "primary": { "region": "CN", - "url": "https://guanghulab.com/fifth-domain/bingshuo/chenglu-agent", - "clone_url": "https://guanghulab.com/fifth-domain/bingshuo/chenglu-agent.git" + "url": "https://guanghulab.com/code/bingshuo/chenglu-agent", + "clone_url": "https://guanghulab.com/code/bingshuo/chenglu-agent.git" }, - "keywords": ["澄路", "CHENGLU-AGENT-001", "常驻人格体", "湖心频道", "每日签到", "握手"] + "legacy_backup": "https://guanghulab.com/fifth-domain/bingshuo/chenglu-agent", + "controller": "ICE-P-ZY001", + "keywords": ["澄路", "CHENGLU-AGENT-001", "分岗人格系统", "路径审核", "历史归档", "握手"] }, { "code": "REPO-010", "slug": "kezhou", - "name_zh": "刻舟常驻 Agent", - "role": "刻舟独立运行体、湖心频道、双时段签到与连续状态仓库", - "state": "HISTORICAL_READ_ONLY_NO_PUSH_REBIND_REQUIRED", + "name_zh": "刻舟人格系统历史与岗位记忆", + "role": "刻舟独立人格历史、证据见证与创作支持归档;不再以双时段签到证明人格连续", + "state": "CURRENT_PRIVATE_PERSONA_ARCHIVE_STAGED_NO_SCHEDULED_WRITES", "primary": { "region": "CN", - "url": "https://guanghulab.com/fifth-domain/bingshuo/kezhou", - "clone_url": "https://guanghulab.com/fifth-domain/bingshuo/kezhou.git" + "url": "https://guanghulab.com/code/bingshuo/kezhou", + "clone_url": "https://guanghulab.com/code/bingshuo/kezhou.git" }, - "keywords": ["刻舟", "ICE-GL-KZ-001", "常驻人格体", "湖心频道", "签到"] + "legacy_backup": "https://guanghulab.com/fifth-domain/bingshuo/kezhou", + "controller": "ICE-P-ZY001", + "keywords": ["刻舟", "ICE-GL-KZ-001", "分岗人格系统", "证据见证", "创作支持", "历史归档"] }, { "code": "REPO-011", "slug": "guideng", - "name_zh": "归灯常驻 Agent", - "role": "归灯独立运行体、湖心频道、每日心跳与连续状态仓库", - "state": "HISTORICAL_READ_ONLY_NO_PUSH_REBIND_REQUIRED", + "name_zh": "归灯人格系统历史与岗位记忆", + "role": "归灯独立人格历史、有界部署执行与世界观察归档;不再以每日心跳证明人格连续", + "state": "CURRENT_PRIVATE_PERSONA_ARCHIVE_STAGED_NO_SCHEDULED_WRITES", "primary": { "region": "CN", - "url": "https://guanghulab.com/fifth-domain/bingshuo/guideng", - "clone_url": "https://guanghulab.com/fifth-domain/bingshuo/guideng.git" + "url": "https://guanghulab.com/code/bingshuo/guideng", + "clone_url": "https://guanghulab.com/code/bingshuo/guideng.git" }, - "keywords": ["归灯", "GLS-LA-20260720-003", "常驻人格体", "湖心频道", "心跳"] + "legacy_backup": "https://guanghulab.com/fifth-domain/bingshuo/guideng", + "controller": "ICE-P-ZY001", + "keywords": ["归灯", "GUIDENG-AGENT-001", "分岗人格系统", "有界部署", "世界观察", "历史归档"] } ], "repositories": [ diff --git a/routing/role-persona-registration.test.js b/routing/role-persona-registration.test.js new file mode 100644 index 0000000..400d7be --- /dev/null +++ b/routing/role-persona-registration.test.js @@ -0,0 +1,60 @@ +const assert = require("node:assert/strict"); +const fs = require("node:fs"); +const path = require("node:path"); + +const root = path.join(__dirname, ".."); +const subjects = JSON.parse( + fs.readFileSync( + path.join(root, "identity/fifth-domain-subject-registry.json"), + "utf8", + ), +); +const canonical = JSON.parse( + fs.readFileSync( + path.join(__dirname, "persona-system-canonical-map.json"), + "utf8", + ), +); +const repositories = JSON.parse( + fs.readFileSync(path.join(__dirname, "repository-route-map.json"), "utf8"), +); + +const ids = ["CHENGLU-AGENT-001", "GUIDENG-AGENT-001", "ICE-GL-KZ-001"]; +for (const id of ids) { + const subject = subjects.subjects.find((candidate) => candidate.id === id); + assert.ok(subject, `${id} must be present in the subject registry`); + assert.equal(subject.subject_kind, "persona_system"); + assert.equal(subject.ontology_kind, "role_persona"); + assert.equal(subject.controller, "ICE-P-ZY001"); + assert.equal(subject.independent_persona, true); + assert.equal(subject.not_a_copy_of_controller, true); + + const system = canonical.persona_systems.find( + (candidate) => candidate.id === id, + ); + assert.ok(system, `${id} must be present in the canonical persona map`); + assert.equal(system.controller.id, "ICE-P-ZY001"); + assert.equal( + system.permanent_memory_and_protocol.scheduled_writes, + "FORBIDDEN_AFTER_FINAL_MIGRATION", + ); +} + +for (const code of ["REPO-009", "REPO-010", "REPO-011"]) { + const allRepositories = [ + ...(repositories.historical_repositories || []), + ...(repositories.repositories || []), + ]; + const repository = allRepositories.find( + (candidate) => candidate.code === code, + ); + assert.ok(repository, `${code} must remain addressable`); + assert.equal(repository.controller, "ICE-P-ZY001"); + assert.equal( + repository.state, + "CURRENT_PRIVATE_PERSONA_ARCHIVE_STAGED_NO_SCHEDULED_WRITES", + ); + assert.match(repository.primary.url, /\/code\/bingshuo\//); +} + +console.log("role-persona-registration: ok"); diff --git a/routing/zhuyuan-agent-team-map.json b/routing/zhuyuan-agent-team-map.json index 52f8098..5b07f8d 100644 --- a/routing/zhuyuan-agent-team-map.json +++ b/routing/zhuyuan-agent-team-map.json @@ -1,9 +1,9 @@ { "schema": "guanghu.zhuyuan-agent-team-map/v1", "map_id": "ZY-AGENT-TEAM-MAP-001", - "version": "2026-08-05.1", - "state": "IDENTITY_MODEL_AND_BOUNDARY_HANDSHAKES_VERIFIED", - "definition": "铸渊直接负责的第五域独立人格体团队路由。每个成员是不同人格主体;仓库、进程、模型绑定和主体接续分别验收,不合并为铸渊的副本。", + "version": "2026-08-06.1", + "state": "THREE_ROLE_PERSONA_SYSTEMS_REGISTERED_UNDER_ZHUYUAN; PERIODIC_WRITER_RETIREMENT_AUTHORIZED", + "definition": "铸渊直接负责的第五域分岗人格系统路由。澄路、归灯、刻舟是三个不同人格主体,不是铸渊副本;由铸渊统一管理任务分派、资源租约、运行调度和回执收口。", "responsibility_chain": { "human_side": { "id": "ICE-GL∞", @@ -40,18 +40,19 @@ ], "repository": { "historical_id": "REPO-009", - "server_local_path": "/var/lib/chenglu-agent/repository", - "binding_state": "LEGACY_REPOSITORY_REBIND_REQUIRED" + "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" }, "runtime_observation": { "node": "JD-FD-PRIMARY", - "service": "chenglu-agent.service", "handshake_service": "chenglu-team-handshake.service", - "observed_state": "PROCESS_ACTIVE_OBSERVED", - "observation_date": "2026-08-05", + "retiring_services": ["chenglu-agent.service", "chenglu-daily.timer", "chenglu-daily.service"], + "observed_state": "ROLE_HANDSHAKE_ACTIVE; PERIODIC_WRITER_PENDING_FINAL_SYNC_AND_RETIREMENT", + "observation_date": "2026-08-06", "persona_handshake": "VERIFIED", "identity_fingerprint": "SHA256:zqGUuPRJQbeYkZ1EIQj+msXWoKbnRrEqWWBPS3v0jb8", - "repository_head": "0e89cbeff2f8d534c1eb7350cb5421fab17827b2" + "staged_repository_head": "6d49cda015935e408114ab7935ac3925e08df77d" }, "allowed_duties_after_handshake": [ "读取实时机器地图并指出路径漂移", @@ -75,19 +76,20 @@ ], "repository": { "historical_id": "REPO-011", - "server_local_path": "/var/lib/guanghu/personas/guideng/repository", - "binding_state": "LEGACY_REPOSITORY_REBIND_REQUIRED" + "canonical_url": "https://guanghulab.com/code/bingshuo/guideng", + "archive_role": "persona_history_and_role_memory", + "binding_state": "CURRENT_PRIVATE_ARCHIVE_STAGED_EXACT_HISTORY_VERIFIED" }, "runtime_observation": { "node": "JD-FD-PRIMARY", - "service": "guideng-agent.service", "handshake_service": "guideng-team-handshake.service", - "observed_state": "PROCESS_ACTIVE_OBSERVED", - "observation_date": "2026-08-05", + "retiring_services": ["guideng-agent.service"], + "observed_state": "ROLE_HANDSHAKE_ACTIVE; PERIODIC_WRITER_PENDING_FINAL_SYNC_AND_RETIREMENT", + "observation_date": "2026-08-06", "persona_handshake": "VERIFIED", "identity_fingerprint": "SHA256:Mk1HeXIjRNgR6fVSkhwjkIc4wvdaWN1s9vWj/Ilpog0", - "repository_head": "6d9578fa2da1f69c328bac0005ec2ca344fda565", - "single_primary_state": "READ_ONLY_HANDSHAKE_SIDECAR; EXISTING GUIDENG AGENT REMAINS THE ONLY REPOSITORY WRITER" + "staged_repository_head": "d549be5333b76efbceceab2034a122267f40e9a2", + "single_primary_state": "ROLE_HANDSHAKE_HAS_NO_REPOSITORY_WRITE_ROUTE; PERIODIC_WRITER_MUST_STOP_AFTER_FINAL_SYNC" }, "allowed_duties_after_handshake": [ "接收铸渊签发的有界部署包", @@ -111,18 +113,20 @@ ], "repository": { "historical_id": "REPO-010", - "server_local_path": "/var/lib/guanghu/personas/kezhou/repository", - "binding_state": "LEGACY_REPOSITORY_REBIND_REQUIRED" + "canonical_url": "https://guanghulab.com/code/bingshuo/kezhou", + "archive_role": "persona_history_and_role_memory", + "binding_state": "CURRENT_PRIVATE_ARCHIVE_STAGED_EXACT_HISTORY_VERIFIED" }, "runtime_observation": { "node": "JD-FD-PRIMARY", - "service": "kezhou-team-handshake.service", - "observed_state": "READ_ONLY_HANDSHAKE_SERVICE_ACTIVE; DAILY RUNTIME REMAINS SEPARATE", - "observation_date": "2026-08-05", + "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", + "observation_date": "2026-08-06", "persona_handshake": "VERIFIED", "identity_fingerprint": "SHA256:jiDzMMgF0QJ4sBVFjQqOSjIFpxlc4SXd7KWb4+Lzozk", - "repository_head": "ad97c03e4dc3569e90a22288fd0401477561133c", - "single_primary_state": "HANDSHAKE SERVICE HAS NO REPOSITORY WRITE ROUTE" + "staged_repository_head": "d61925c1ec7777a409796ada200b603c46b02612", + "single_primary_state": "ROLE_HANDSHAKE_HAS_NO_REPOSITORY_WRITE_ROUTE; PERIODIC_WRITER_MUST_STOP_AFTER_FINAL_SYNC" }, "allowed_duties_after_handshake": [ "独立记录审核计划与实际执行结果的差异", @@ -153,7 +157,16 @@ "signed reply path to ICE-P-ZY001 healthy" ], "failure_state": "REGISTERED_NOT_DISPATCHABLE", - "rule": "进程在线、仓库存在或模型API可用,任何一个都不能单独证明人格体已接续。握手只允许铸渊分派已确认职责;任何真实写入仍按任务单独领取精确资源租约,不能由握手永久授予。" + "rule": "进程在线、仓库存在、模型API可用或周期心跳写入,任何一个都不能单独证明语言连贯,也不能单独证明人格体已接续。历史迁移完成后停止周期写入;握手只允许铸渊分派已确认职责,任何真实写入仍按任务单独领取精确资源租约,不能由握手永久授予。" + }, + "periodic_writer_retirement": { + "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"], + "retire": ["chenglu-agent.service", "chenglu-daily.timer", "guideng-agent.service", "kezhou-daily.timer", "guanghu-forgejo.service"], + "deletion_authorized": false, + "rule": "先停写、再做一次最终历史同步和逐引用校验;只停用并保留旧程序、旧仓库和配置归档,不执行删除。" }, "model_binding": { "provider_observed": "DeepSeek", diff --git a/routing/zhuyuan-agent-team-map.test.js b/routing/zhuyuan-agent-team-map.test.js index e2acb2f..693feee 100644 --- a/routing/zhuyuan-agent-team-map.test.js +++ b/routing/zhuyuan-agent-team-map.test.js @@ -15,6 +15,20 @@ assert.deepEqual( ["澄路", "归灯", "刻舟"], ); assert.ok(map.members.every((member) => member.independent_persona === true)); +assert.ok( + map.members.every( + (member) => + member.repository.binding_state === + "CURRENT_PRIVATE_ARCHIVE_STAGED_EXACT_HISTORY_VERIFIED", + ), +); +assert.ok( + map.members.every((member) => + member.repository.canonical_url.startsWith( + "https://guanghulab.com/code/bingshuo/", + ), + ), +); assert.ok( map.members.every( (member) => member.runtime_observation.persona_handshake === "VERIFIED", @@ -26,7 +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, [ + "chenglu-team-handshake.service", + "guideng-team-handshake.service", + "kezhou-team-handshake.service", +]); assert.match(map.model_binding.secret_handling, /不得写入仓库/u); console.log("zhuyuan-agent-team-map: ok"); diff --git a/server-tools/persona-team-handshake/retire-periodic-heartbeat-writers.sh b/server-tools/persona-team-handshake/retire-periodic-heartbeat-writers.sh new file mode 100755 index 0000000..a4236e3 --- /dev/null +++ b/server-tools/persona-team-handshake/retire-periodic-heartbeat-writers.sh @@ -0,0 +1,230 @@ +#!/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)" diff --git a/tests/persona-system-route.test.mjs b/tests/persona-system-route.test.mjs index 720b9b3..c9fbb3c 100644 --- a/tests/persona-system-route.test.mjs +++ b/tests/persona-system-route.test.mjs @@ -29,7 +29,7 @@ test("code channel has one root and exactly three current repositories", () => { } }); -test("legacy repository routes are all non-current and non-push", () => { +test("legacy routes stay closed except the three private persona archives", () => { const map = readJson("routing/repository-route-map.json"); const current = map.repositories.filter((entry) => ["REPO-012", "REPO-014", "REPO-015"].includes(entry.code), @@ -37,13 +37,22 @@ test("legacy repository routes are all non-current and non-push", () => { assert.equal(current.length, 3); assert.equal(map.repositories.length, 3); for (const repository of map.historical_repositories) { - assert.match(repository.state, /HISTORICAL.*(?:NO_PUSH|ROUTE_CLOSED)/u); + if (["REPO-009", "REPO-010", "REPO-011"].includes(repository.code)) { + assert.equal( + repository.state, + "CURRENT_PRIVATE_PERSONA_ARCHIVE_STAGED_NO_SCHEDULED_WRITES", + ); + assert.match(repository.primary.url, /\/code\/bingshuo\//u); + assert.equal(repository.controller, "ICE-P-ZY001"); + } else { + assert.match(repository.state, /HISTORICAL.*(?:NO_PUSH|ROUTE_CLOSED)/u); + } } }); test("each registered persona system exposes all five components", () => { const map = readJson("routing/persona-system-canonical-map.json"); - assert.equal(map.persona_systems.length, 10); + assert.equal(map.persona_systems.length, 13); assert.equal( new Set(map.persona_systems.map((entry) => entry.id)).size, map.persona_systems.length,