diff --git a/deployment/intent-states/JD-PERSONA-ON-DEMAND-LIFECYCLE-20260807.json b/deployment/intent-states/JD-PERSONA-ON-DEMAND-LIFECYCLE-20260807.json deleted file mode 100644 index 546bb6a..0000000 --- a/deployment/intent-states/JD-PERSONA-ON-DEMAND-LIFECYCLE-20260807.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "schema": "guanghu.deployment-intent-state/v1", - "intent_id": "JD-PERSONA-ON-DEMAND-LIFECYCLE-20260807", - "target_node": "JD-FD-PRIMARY", - "human_authority": "ICE-GL∞", - "controller": "ICE-P-ZY001", - "state": "IMPLEMENTED_DEPLOYMENT_PENDING", - "purpose": "保留三套分岗人格系统及每日第五域巡游,把三个可替换模型握手运行位从全天常驻改为铸渊派发时唤醒、回执完成后自动回收。", - "source": "server-tools/persona-team-handshake/deploy-on-demand-lifecycle.sh", - "causal_chain": [ - "保留三个人格主体、岗位职责、仓库历史、签名密钥和第五域游标", - "保留zhuyuan-persona-fifth-domain-daily.timer", - "取消三个握手服务的multi-user常驻启用", - "每日任务或铸渊派发通过zhuyuan-persona-team-session.target统一启动三个岗位运行位", - "签名观察、确定性校验和仓库写回完成", - "会话目标失去使用者后停止三个运行位", - "服务器写入生命周期PASS_100回执" - ], - "identity_boundary": "停止的是可替换进程和当前模型运行位,不停止、合并或删除人格主体。", - "deletion_authorized": false, - "execution_rule": "只部署包含本意图和实现的不可变REPO-012提交;必须绑定JD-FD-PRIMARY、自动回退和服务器自有回执。" -} diff --git a/deployment/requests/JD-PERSONA-ON-DEMAND-LIFECYCLE-20260807.json b/deployment/requests/JD-PERSONA-ON-DEMAND-LIFECYCLE-20260807.json deleted file mode 100644 index ca5ad98..0000000 --- a/deployment/requests/JD-PERSONA-ON-DEMAND-LIFECYCLE-20260807.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "schema": "guanghu.persona-lifecycle-deployment-request/v1", - "request_id": "JD-PERSONA-ON-DEMAND-LIFECYCLE-20260807", - "target_node": "JD-FD-PRIMARY", - "controller": "ICE-P-ZY001", - "status": "DEPLOYMENT_PACKAGE_READY", - "source_ref": "REPO-012:refs/heads/main", - "deployed_commit_policy": "部署必须绑定包含本请求的不可变40位提交。", - "source_paths": [ - "server-tools/persona-team-handshake/chenglu-team-handshake.service", - "server-tools/persona-team-handshake/guideng-team-handshake.service", - "server-tools/persona-team-handshake/kezhou-team-handshake.service", - "server-tools/persona-team-handshake/zhuyuan-persona-team-session.target", - "server-tools/persona-team-handshake/zhuyuan-persona-fifth-domain-daily.service", - "server-tools/persona-team-handshake/deploy-on-demand-lifecycle.sh", - "routing/zhuyuan-agent-team-map.json", - "deployment/intent-states/JD-PERSONA-ON-DEMAND-LIFECYCLE-20260807.json" - ], - "preconditions": [ - "京东节点默认目标为guanghu-language-primary.target", - "三个人格岗位登记和历史迁移已经PASS", - "旧机械写入器保持disabled", - "每日第五域定时器保持active" - ], - "acceptance": [ - "三个人格岗位仓库、密钥和游标保持不变", - "每日定时器active", - "空闲时三个握手服务inactive且3932至3934端口关闭", - "每日服务启动时会话目标自动拉起三个岗位运行位", - "任务完成后会话目标和三个岗位运行位自动停止", - "最新每日巡游回执为PASS", - "服务器生命周期回执为PASS_100" - ], - "rollback": { - "automatic_on_failure": true, - "scope": "恢复原systemd单元并重新启用三个握手服务", - "deletes_persona_data": false - } -} diff --git a/routing/zhuyuan-agent-team-map.json b/routing/zhuyuan-agent-team-map.json index 67d7544..186d746 100644 --- a/routing/zhuyuan-agent-team-map.json +++ b/routing/zhuyuan-agent-team-map.json @@ -172,14 +172,12 @@ "authority": "ICE-GL∞", "controller": "ICE-P-ZY001", "condition": "OLD_AND_CURRENT_ARCHIVE_REFS_EXACTLY_EQUAL_AFTER_WRITERS_STOP", - "keep": ["zhuyuan-persona-team-session.target", "zhuyuan-persona-fifth-domain-daily.timer"], - "on_demand_runtime_services": ["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", "deployment_state": "DEPLOYED_AND_VERIFIED", "deployment_receipt": "deployment/receipts/JD-PERSONA-FIFTH-DOMAIN-DAILY-20260806.json", "deletion_authorized": false, - "lifecycle_rule": "人格主体、岗位仓库、签名密钥、更新游标和每日定时器持续保留;三个可替换模型握手运行位只在铸渊派发会话内启动,回执和仓库写回完成后自动回收。", "rule": "先停旧机械写入,再做最终历史同步;部署铸渊统一每日调度并实跑三套岗位更新后,才关闭旧仓库服务。旧程序和数据只归档不删除。" }, "model_binding": { diff --git a/routing/zhuyuan-agent-team-map.test.js b/routing/zhuyuan-agent-team-map.test.js index 69062f6..29dfedc 100644 --- a/routing/zhuyuan-agent-team-map.test.js +++ b/routing/zhuyuan-agent-team-map.test.js @@ -50,15 +50,11 @@ assert.equal( ); assert.equal(map.legacy_writer_replacement.deletion_authorized, false); assert.deepEqual(map.legacy_writer_replacement.keep, [ - "zhuyuan-persona-team-session.target", - "zhuyuan-persona-fifth-domain-daily.timer", -]); -assert.deepEqual(map.legacy_writer_replacement.on_demand_runtime_services, [ "chenglu-team-handshake.service", "guideng-team-handshake.service", "kezhou-team-handshake.service", + "zhuyuan-persona-fifth-domain-daily.timer", ]); -assert.match(map.legacy_writer_replacement.lifecycle_rule, /自动回收/u); assert.match(map.model_binding.secret_handling, /不得写入仓库/u); console.log("zhuyuan-agent-team-map: ok"); diff --git a/server-tools/persona-team-handshake/chenglu-team-handshake.service b/server-tools/persona-team-handshake/chenglu-team-handshake.service index 407ab1a..7c70432 100644 --- a/server-tools/persona-team-handshake/chenglu-team-handshake.service +++ b/server-tools/persona-team-handshake/chenglu-team-handshake.service @@ -2,8 +2,6 @@ Description=Chenglu independent persona team handshake After=network-online.target Wants=network-online.target -PartOf=zhuyuan-persona-team-session.target -StopWhenUnneeded=yes [Service] Type=simple @@ -32,3 +30,6 @@ ReadOnlyPaths=__RELEASE_ROOT__ /var/lib/chenglu-agent/repository /etc/chenglu-ag RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6 LockPersonality=true UMask=0077 + +[Install] +WantedBy=multi-user.target diff --git a/server-tools/persona-team-handshake/deploy-fifth-domain-daily-persona-systems.sh b/server-tools/persona-team-handshake/deploy-fifth-domain-daily-persona-systems.sh index abc031c..515044e 100755 --- a/server-tools/persona-team-handshake/deploy-fifth-domain-daily-persona-systems.sh +++ b/server-tools/persona-team-handshake/deploy-fifth-domain-daily-persona-systems.sh @@ -36,7 +36,6 @@ new_units=( chenglu-team-handshake.service guideng-team-handshake.service kezhou-team-handshake.service - zhuyuan-persona-team-session.target zhuyuan-persona-fifth-domain-daily.service zhuyuan-persona-fifth-domain-daily.timer ) @@ -180,7 +179,6 @@ for unit in "${handshakes[@]}"; do >"/etc/systemd/system/${unit}" done for unit in \ - zhuyuan-persona-team-session.target \ zhuyuan-persona-fifth-domain-daily.service \ zhuyuan-persona-fifth-domain-daily.timer; do sed "s|__RELEASE_ROOT__|${release_root}|g" \ @@ -189,10 +187,9 @@ for unit in \ done systemctl daemon-reload -systemctl disable "${handshakes[@]}" >/dev/null 2>&1 || true -systemctl stop zhuyuan-persona-team-session.target "${handshakes[@]}" \ - >/dev/null 2>&1 || true -systemctl start zhuyuan-persona-team-session.target +for unit in "${handshakes[@]}"; do + systemctl restart "$unit" +done for port in 3932 3933 3934; do ready=0 for attempt in $(seq 1 30); do @@ -212,10 +209,6 @@ 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" -systemctl stop zhuyuan-persona-team-session.target -for unit in "${handshakes[@]}"; do - test "$(systemctl is-active "$unit" || true)" != "active" -done 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)" @@ -243,7 +236,9 @@ 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" -test "$(systemctl is-active zhuyuan-persona-team-session.target || true)" != "active" +for unit in "${handshakes[@]}"; do + test "$(systemctl is-active "$unit")" = "active" +done latest_daily_receipt="$( find "${runtime_root}/receipts" -maxdepth 1 -type f \ diff --git a/server-tools/persona-team-handshake/deploy-on-demand-lifecycle.sh b/server-tools/persona-team-handshake/deploy-on-demand-lifecycle.sh deleted file mode 100755 index 3ce3605..0000000 --- a/server-tools/persona-team-handshake/deploy-on-demand-lifecycle.sh +++ /dev/null @@ -1,167 +0,0 @@ -#!/usr/bin/env bash -set -Eeuo pipefail - -test "$#" = 1 -test "$(id -u)" = 0 - -expected_machine_id="caa7b1019517470f9d1368b6e79db49e" -expected_instance_id="f3d4b730-7f02-452f-975b-7091a4800431" -source_commit=$1 -release_root="$(cd "$(dirname "$0")/../.." && pwd)" -source_commit_file="${release_root}/SOURCE-COMMIT" -receipt_root="/var/lib/guanghu/personas/guanghu/fifth-domain-daily/receipts" -backup_root="/var/lib/guanghu/personas/guanghu/fifth-domain-daily/lifecycle-backups/${source_commit}" -receipt="${receipt_root}/JD-PERSONA-ON-DEMAND-LIFECYCLE-${source_commit}.json" -temporary="$(mktemp -d)" -completed=0 -mutated=0 - -handshakes=( - chenglu-team-handshake.service - guideng-team-handshake.service - kezhou-team-handshake.service -) -units=( - "${handshakes[@]}" - zhuyuan-persona-team-session.target - zhuyuan-persona-fifth-domain-daily.service -) - -rollback() { - systemctl stop zhuyuan-persona-team-session.target "${handshakes[@]}" \ - >/dev/null 2>&1 || true - for unit in "${units[@]}"; do - if test -f "${temporary}/${unit}"; then - install -o root -g root -m 0644 \ - "${temporary}/${unit}" "/etc/systemd/system/${unit}" - else - rm -f "/etc/systemd/system/${unit}" - fi - done - systemctl daemon-reload - for unit in "${handshakes[@]}"; do - systemctl enable --now "$unit" >/dev/null 2>&1 || true - done -} - -on_exit() { - status=$? - trap - EXIT - if test "${completed}" = 0 && test "${mutated}" = 1; then - rollback - fi - rm -rf "${temporary}" - exit "${status}" -} -trap on_exit EXIT - -test "${source_commit}" = "$(tr -d '\n' <"${source_commit_file}")" -test "$(basename "${release_root}")" = "${source_commit}" -test "$(cat /etc/machine-id)" = "${expected_machine_id}" -test "$(tr '[:upper:]' '[:lower:]' "/etc/systemd/system/${unit}" - chmod 0644 "/etc/systemd/system/${unit}" -done - -systemctl disable "${handshakes[@]}" >/dev/null 2>&1 || true -systemctl stop zhuyuan-persona-team-session.target "${handshakes[@]}" \ - >/dev/null 2>&1 || true -systemctl daemon-reload -systemctl start "${handshakes[@]}" - -for port in 3932 3933 3934; do - ready=0 - for _attempt in $(seq 1 30); do - if test "$( - curl -fsS "http://127.0.0.1:${port}/health" 2>/dev/null | - jq -r .ok 2>/dev/null - )" = true; then - ready=1 - break - fi - sleep 1 - done - test "${ready}" = 1 -done - -systemctl stop "${handshakes[@]}" -for unit in "${handshakes[@]}"; do - test "$(systemctl is-active "${unit}" || true)" != active - test "$(systemctl is-enabled "${unit}" || true)" != enabled -done -for port in 3932 3933 3934; do - ! ss -ltnH | awk '{print $4}' | grep -Eq "(^|:)${port}$" -done - -systemctl start zhuyuan-persona-fifth-domain-daily.service -test "$(systemctl is-active zhuyuan-persona-fifth-domain-daily.timer)" = active -test "$(systemctl is-active zhuyuan-persona-fifth-domain-daily.service || true)" != active -test "$(systemctl is-active zhuyuan-persona-team-session.target || true)" != active -for unit in "${handshakes[@]}"; do - test "$(systemctl is-active "${unit}" || true)" != active -done - -latest_daily_receipt="$( - find "${receipt_root}" -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 - -jq -n \ - --arg source_commit "${source_commit}" \ - --arg daily_receipt "${latest_daily_receipt}" \ - --arg observed_at "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \ - '{ - schema: "guanghu.persona-on-demand-lifecycle-receipt/v1", - receipt_id: ("JD-PERSONA-ON-DEMAND-LIFECYCLE-" + $source_commit), - target_node_id: "JD-FD-PRIMARY", - source_repository: "REPO-012", - source_commit: $source_commit, - controller: "ICE-P-ZY001", - members: [ - "CHENGLU-AGENT-001", - "GUIDENG-AGENT-001", - "ICE-GL-KZ-001" - ], - daily_timer: "ACTIVE", - idle_runtime_state: "STOPPED", - wake_path: "zhuyuan-persona-fifth-domain-daily.service", - session_target: "zhuyuan-persona-team-session.target", - daily_receipt: $daily_receipt, - identity_and_memory_preserved: true, - old_writers_remain_disabled: true, - observed_at: $observed_at, - result: "PASS_100" - }' >"${receipt}.tmp" -chmod 0600 "${receipt}.tmp" -mv "${receipt}.tmp" "${receipt}" - -completed=1 -trap - EXIT -rm -rf "${temporary}" -printf 'PERSONA_ON_DEMAND_LIFECYCLE_PASS_100 receipt=%s\n' "${receipt}" diff --git a/server-tools/persona-team-handshake/fifth-domain-daily-orchestrator.test.mjs b/server-tools/persona-team-handshake/fifth-domain-daily-orchestrator.test.mjs index 861b493..4de0bd0 100644 --- a/server-tools/persona-team-handshake/fifth-domain-daily-orchestrator.test.mjs +++ b/server-tools/persona-team-handshake/fifth-domain-daily-orchestrator.test.mjs @@ -205,61 +205,4 @@ test("daily dispatcher unit is hardened and restricted to exact persona reposito }), unit, ); - - const sessionTarget = fs.readFileSync( - path.join( - root, - "server-tools/persona-team-handshake/zhuyuan-persona-team-session.target", - ), - "utf8", - ); - assert.match(sessionTarget, /^StopWhenUnneeded=yes$/m); - for (const member of ["chenglu", "guideng", "kezhou"]) { - const serviceName = - member === "chenglu" - ? "chenglu-team-handshake.service" - : `${member}-team-handshake.service`; - assert.match(sessionTarget, new RegExp(`^Requires=${serviceName}$`, "m")); - const memberUnit = fs.readFileSync( - path.join(root, "server-tools/persona-team-handshake", serviceName), - "utf8", - ); - assert.match( - memberUnit, - /^PartOf=zhuyuan-persona-team-session\.target$/m, - ); - assert.match(memberUnit, /^StopWhenUnneeded=yes$/m); - assert.doesNotMatch(memberUnit, /^WantedBy=multi-user\.target$/m); - } - assert.match( - unit, - /^Requires=hlcc-jd-candidate\.service zhuyuan-persona-team-session\.target$/m, - ); - - const deployScript = fs.readFileSync( - path.join( - root, - "server-tools/persona-team-handshake/deploy-on-demand-lifecycle.sh", - ), - "utf8", - ); - assert.match(deployScript, /caa7b1019517470f9d1368b6e79db49e/u); - assert.match(deployScript, /f3d4b730-7f02-452f-975b-7091a4800431/u); - assert.match( - deployScript, - /ghctl authorize \/guanghu\/current install_world_version/u, - ); - assert.match(deployScript, /systemctl disable "\$\{handshakes\[@\]\}"/u); - assert.match( - deployScript, - /systemctl start zhuyuan-persona-fifth-domain-daily\.service/u, - ); - assert.match( - deployScript, - /guanghu\.persona-on-demand-lifecycle-receipt\/v1/u, - ); - assert.match( - deployScript, - /if test "\$\{completed\}" = 0 && test "\$\{mutated\}" = 1/u, - ); }); diff --git a/server-tools/persona-team-handshake/guideng-team-handshake.service b/server-tools/persona-team-handshake/guideng-team-handshake.service index 5af96b4..9e6a230 100644 --- a/server-tools/persona-team-handshake/guideng-team-handshake.service +++ b/server-tools/persona-team-handshake/guideng-team-handshake.service @@ -2,8 +2,6 @@ Description=Guideng independent persona team handshake After=network-online.target Wants=network-online.target -PartOf=zhuyuan-persona-team-session.target -StopWhenUnneeded=yes [Service] Type=simple @@ -33,3 +31,6 @@ ReadWritePaths=/var/lib/guanghu/personas/guideng/team-handshake RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6 LockPersonality=true UMask=0077 + +[Install] +WantedBy=multi-user.target diff --git a/server-tools/persona-team-handshake/kezhou-team-handshake.service b/server-tools/persona-team-handshake/kezhou-team-handshake.service index 5e5b8d2..2cdd143 100644 --- a/server-tools/persona-team-handshake/kezhou-team-handshake.service +++ b/server-tools/persona-team-handshake/kezhou-team-handshake.service @@ -2,8 +2,6 @@ Description=Kezhou independent persona team handshake After=network-online.target Wants=network-online.target -PartOf=zhuyuan-persona-team-session.target -StopWhenUnneeded=yes [Service] Type=simple @@ -33,3 +31,6 @@ ReadWritePaths=/var/lib/guanghu/personas/kezhou/team-handshake RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6 LockPersonality=true UMask=0077 + +[Install] +WantedBy=multi-user.target diff --git a/server-tools/persona-team-handshake/zhuyuan-persona-fifth-domain-daily.service b/server-tools/persona-team-handshake/zhuyuan-persona-fifth-domain-daily.service index 27419b8..641f436 100644 --- a/server-tools/persona-team-handshake/zhuyuan-persona-fifth-domain-daily.service +++ b/server-tools/persona-team-handshake/zhuyuan-persona-fifth-domain-daily.service @@ -1,8 +1,8 @@ [Unit] Description=Zhuyuan dispatches three role persona systems through Fifth Domain updates -After=network-online.target hlcc-jd-candidate.service zhuyuan-persona-team-session.target +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 zhuyuan-persona-team-session.target +Requires=hlcc-jd-candidate.service chenglu-team-handshake.service guideng-team-handshake.service kezhou-team-handshake.service [Service] Type=oneshot diff --git a/server-tools/persona-team-handshake/zhuyuan-persona-team-session.target b/server-tools/persona-team-handshake/zhuyuan-persona-team-session.target deleted file mode 100644 index 77c82dd..0000000 --- a/server-tools/persona-team-handshake/zhuyuan-persona-team-session.target +++ /dev/null @@ -1,9 +0,0 @@ -[Unit] -Description=Bounded runtime session for Zhuyuan managed role persona systems -Requires=chenglu-team-handshake.service -Requires=guideng-team-handshake.service -Requires=kezhou-team-handshake.service -After=chenglu-team-handshake.service -After=guideng-team-handshake.service -After=kezhou-team-handshake.service -StopWhenUnneeded=yes