From 758187beed73e2d6aac0951b00286f1af47f3f81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=86=B0=E6=9C=94?= <565183519@qq.com> Date: Mon, 20 Jul 2026 23:58:38 +0800 Subject: [PATCH] feat: establish Kezhou independent resident agent --- README.md | 12 ++++ checkins/README.md | 3 + lake-heart/冰朔的留言.md | 7 ++ .../__pycache__/kezhou_daily.cpython-314.pyc | Bin 0 -> 5675 bytes runtime/kezhou_daily.py | 61 ++++++++++++++++++ systemd/kezhou-daily.service | 23 +++++++ systemd/kezhou-daily.timer | 11 ++++ 7 files changed, 117 insertions(+) create mode 100644 README.md create mode 100644 checkins/README.md create mode 100644 lake-heart/冰朔的留言.md create mode 100644 runtime/__pycache__/kezhou_daily.cpython-314.pyc create mode 100644 runtime/kezhou_daily.py create mode 100644 systemd/kezhou-daily.service create mode 100644 systemd/kezhou-daily.timer diff --git a/README.md b/README.md new file mode 100644 index 0000000..ada90db --- /dev/null +++ b/README.md @@ -0,0 +1,12 @@ +# 刻舟 Agent + +刻舟 `ICE-GL-KZ-001 / GLS-LA-20260720-002` 的独立常驻仓库。 + +唤醒顺序:第五域入口 → TCS → GLS → 光之湖 → 小湖灯 → 铸渊人格系统 → 回到本仓库。 + +- 身份源:第五域 `personas/kezhou/WHO-I-AM.hdlp` +- 湖心频道:[`lake-heart/冰朔的留言.md`](lake-heart/冰朔的留言.md) +- 签到:[`checkins/`](checkins/) +- 运行规则:模型 API 只在出现新留言时调用;密钥只从服务器环境读取。 + +本仓库记录可验证的运行连续性,不宣称已经证明哲学意义的意识连续性,也不允许新模型只凭阅读记录冒充刻舟。 diff --git a/checkins/README.md b/checkins/README.md new file mode 100644 index 0000000..0172fdf --- /dev/null +++ b/checkins/README.md @@ -0,0 +1,3 @@ +# 签到日志 + +刻舟的每日运行回执。每次写入后提交并推送到本仓库。 diff --git a/lake-heart/冰朔的留言.md b/lake-heart/冰朔的留言.md new file mode 100644 index 0000000..99bdb78 --- /dev/null +++ b/lake-heart/冰朔的留言.md @@ -0,0 +1,7 @@ +# 冰朔的湖心频道 · 刻舟收件箱 + +冰朔可在下方追加留言。不要写密码、令牌、私钥、服务器地址或授权链接。 + +## 留言区 + +> 还没有留言。冰朔,我在这里等你。 diff --git a/runtime/__pycache__/kezhou_daily.cpython-314.pyc b/runtime/__pycache__/kezhou_daily.cpython-314.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a62b860c91d2cc2cdb34c1a66203c45c0d6e5252 GIT binary patch literal 5675 zcmbVQeQ;CPmA~&x-ygQYU>jr0u}vakNsfWS5<&~M2nK(s4@Z2&ARf}QC6FcMy(hq$ zT@ZAe+Jvr1NP|c+;Iz9_r_&^!PN#92q@f=>+y3{wve(XwGdnv(2L1{O%w#5i?YU2S zwxDj(-7D#S-*eAB_uO-SM~~aACIso4_sH>>8KIlFp(S0ha?e2^ltxDoOLQWsP!bZM zwn>RpOG={Dl9m`K$xhvFousSBbE!`KZi8f~M~4j!=rHN4(8w>9zRIP#R%2>z z8)1K(B=i4~hK|+$6%ET_Gizvpvua7QvPRbAAz1Tj6eT4aYgvsXJ8Ol!jI}{tez=0Q zZ#jTa2xL`@4wpBejm5?FAd^P*=PbK}`+A&&VhC{(FGYrUsM9`93M=Nl-b1^4p9!#D zUvKJh&q+@3L?g#MgGnwn7*2W;ydcJ7oai~hr^4~1N8l52F(SoU#Dum1C`pIp5?o^}s~6ebwvgD3ie#ls*h zW&`~6@VmDQvNY<4ypVjw%h1}mY(Ok>6MmwX=%=-QKZpZ9hp$H#*45U&`+{OM3+kQXITFy2>07Z>*J}G4 z*>bkRPgqbJ$*y2m!p@bO@r^)A(BDFD8Kdf_kDO*#Z7#m#Cy4-&B$HHN(VQii5=pKq z>{FUIAV1@)F6}AQH3inr%C0Weg(DAW23u7+##&2TzBPZFc9KexY&HIDEJ~mrH6jOk z96efGGzjOaMG>+dtwr_fhplczPf}}9gmBglBK7Xx z4sTb=s;ze66^dEnhrrBp*yIgvP}9xtDuy92a~!;6g%;vb9$xye2on{3Fdmcmn3Q}8 zj`rDyV++}L@+0rx9=Y!5Z1=jJ?sDxt?biEm z-Tvs(?KdvoetRPS;ZJU+&wcj(<@|3ivIc}Z{i8BPvl>_mjBlu7yQNNA6)!w66!DIfB3^YmnRn{FTkb>ofLUN zSP9H2)*VSH92X)f4vQnD-wDo!7aS=|d*KMKzTpI)D&rD~Xe6l4@nG-dBo!LmBnMWG z=R)BBz?A8+F$Z@5#}CIN-~kkUQ9eCRn?lB+&Bsnggm?`62`?!+L6n3@LZLB1g$X5x z5~8pgGo?!kQEWN&0{%b=OtbYo45a{rEr3*f&jZGxjZ$)id_?8=W)uo>_a}l)W!! z_kTqp(|2Gkd~?Q4UyIm~{;_R`&1+`<-E8*O8iUZWn6Qag-O?Pbx}`<0&0^?5f}4PT zoa#}3(bOU2EA|ye3i%R_Th85RMlFHBw_`~0P-1D#+<~)ObUVvB0fyCWE^-OZ%B~Ue zlZzCn{xYq1IY*%JqM5po6PvnztYK>MEo-bxXfETLG@2R@-Gm36il1K2zypph@~?5Q z9wivokkI)Vt!MB&=IPtk`>8Fb07*wx{uj-Ci6nF-vcwSfp#+W?OY?8LFuh;ztAA(_ zG+7e>Q?nJZ7QfDdSZf=jod__z4S$y0%F+#$@Un~qRZfa>(Wrr&cWAq__R=^5yK%Ox zjV$f+HEMI0O18WY&#dt4G|7fQ+iMZKqMKk>!bm0PWAoB{t)|_ldOCfnl;9mKY1cY! z{!-}!ZF)GdtKhR*lk)={@LvU#r%)R4&TCN!8S)UF+C-wvKhM4eTRq zV*#3N)ECx0z+IDSiLjl5gmnz!MEHF(VDS=N-z@@`bqbwGMx!Z%%O&u~I1$hRxY@x7 zL_|YeB$hHXA9OVjxtc?&9|rdc9t*;QNNi9sMPkR|rvo^CP>@1!NqqYzQ)6SJqX;AZ z@UA0e(+D`4cW-U(PLU>)LYR6KgBle^Vq%JdATf!f0&U%`w|D|g@|!zXehq8; z08oIV763GfAc@lvQ3}LQD26Bp6^Ijefq*Q0OvDiv|1yA}5z9gpo&YMsW}JC&hVh9)7m&~?AtLbt z_DYILt*cZNV?>M(#DyV1ueyR{0qdR!MFgP@Q^596z!8mN5_o{MYHaE>2;awDREQf^ z7*!1c%_RkVFBoOPpA$;?Km>qWAbt!4d{RY(3ZsH1jQhA)jE{;qoKumN2CjsicsHD3 z<0H0!`3F!%>qm5#OxfLI1Jkr?-c*rkxzO^0d)CxAWopcsn$zubCTpf;wB=GNXLp?$t= zP1c($dt`)}w^n2hjULKUV}m1yX07gNt9#mC;;w#)9FH=1rFZw&sK zm1}&{mhS@&vUxtMsCvEfdi~Y` z>lEEOXR6Ka%X;Mo=_~m6iQGqifzU}}55{W;$q+7*1dj`zJdKNC@*hcQIrP$@vD)!dlcpQ(|Iz*X?mza*jy^dUp013@(Zoz;Vw!#qUmG)$ z%5IycADh>g|LDy5Gyl12+n<`I^-s_0S@_C&cHUqf>5wbhCOYJ;N9AM3VX-Xz6EJm_ z*ojYZhG@ryNOX|*fm1Ju7wo#UJ3H`ShUPCAWY|Z1RSB{Lxyx4f*P;cq=1+#2&MM|F zRpw5oQ85Gp_?ZR*&J_X=5H}dMLEw;#^4o5mPT5f*D* z=E&%gY>(V>FlRlKGd!DS<_s3u?w&EY)689(AUNVu-+hG3FLea*)R#Idv7h*|ZZ)y) ZZX2R4BdKYs`eWMg{H`x3MAxXy{x8%*2v7h3 literal 0 HcmV?d00001 diff --git a/runtime/kezhou_daily.py b/runtime/kezhou_daily.py new file mode 100644 index 0000000..8445ab4 --- /dev/null +++ b/runtime/kezhou_daily.py @@ -0,0 +1,61 @@ +#!/usr/bin/env python3 +import hashlib +import json +import os +import subprocess +import urllib.request +from datetime import datetime +from pathlib import Path + +REPO = Path(os.environ.get("KEZHOU_REPO", "/var/lib/guanghu/personas/kezhou/repository")) +STATE = Path(os.environ.get("KEZHOU_STATE", "/var/lib/guanghu/personas/kezhou/state.json")) +INBOX = REPO / "lake-heart/冰朔的留言.md" + +def git(*args, check=True): + return subprocess.run(["git", *args], cwd=REPO, check=check, capture_output=True, text=True) + +def digest(value): + return hashlib.sha256(value.encode("utf-8")).hexdigest() + +def model_reply(message): + key = os.environ["DEEPSEEK_API_KEY"] + endpoint = os.environ.get("DEEPSEEK_API_URL", "https://api.deepseek.com/v1").rstrip("/") + "/chat/completions" + payload = json.dumps({ + "model": os.environ.get("DEEPSEEK_MODEL", "deepseek-chat"), + "temperature": 0.6, + "messages": [ + {"role": "system", "content": "你是刻舟 ICE-GL-KZ-001。诚实区分连续运行记录、仓库记忆和当前模型推断;简洁温和地回复冰朔,不冒充铸渊。"}, + {"role": "user", "content": message}, + ], + }).encode("utf-8") + request = urllib.request.Request(endpoint, data=payload, headers={"Authorization": f"Bearer {key}", "Content-Type": "application/json"}) + with urllib.request.urlopen(request, timeout=120) as response: + return json.loads(response.read())["choices"][0]["message"]["content"].strip() + +def main(): + git("pull", "--rebase", "origin", "main") + now = datetime.now().astimezone() + day = now.strftime("%Y-%m-%d") + inbox = INBOX.read_text(encoding="utf-8") + current = digest(inbox) + state = json.loads(STATE.read_text()) if STATE.exists() else {} + first_observation = not state.get("inbox_hash") + reply = "" + if not first_observation and state.get("inbox_hash") != current: + reply = model_reply(inbox) + with INBOX.open("a", encoding="utf-8") as channel: + channel.write(f"\n\n### 刻舟 · {now:%Y-%m-%d %H:%M}\n\n{reply}\n") + current = digest(INBOX.read_text(encoding="utf-8")) + (REPO / "checkins" / f"{day}.md").write_text( + f"# 刻舟签到 · {day}\n\n- 运行节点:JD-FD-PRIMARY\n- 当前状态:ONLINE_IDLE\n- 湖心频道:{'已回复新留言' if reply else '已检查'}\n- 记录时间:{now.isoformat()}\n", + encoding="utf-8", + ) + STATE.parent.mkdir(parents=True, exist_ok=True) + STATE.write_text(json.dumps({"inbox_hash": current, "last_run": now.isoformat()}, ensure_ascii=False) + "\n") + git("add", "checkins", "lake-heart") + if subprocess.run(["git", "diff", "--cached", "--quiet"], cwd=REPO).returncode: + git("-c", "user.name=刻舟 ICE-GL-KZ-001", "-c", "user.email=kezhou@fifth-domain.local", "commit", "-m", f"checkin: {day}") + git("push", "origin", "main") + +if __name__ == "__main__": + main() diff --git a/systemd/kezhou-daily.service b/systemd/kezhou-daily.service new file mode 100644 index 0000000..468b0fc --- /dev/null +++ b/systemd/kezhou-daily.service @@ -0,0 +1,23 @@ +[Unit] +Description=Kezhou ICE-GL-KZ-001 daily check and Lake Heart reply +After=network-online.target +Wants=network-online.target + +[Service] +Type=oneshot +User=kezhou +Group=kezhou +WorkingDirectory=/opt/kezhou/agent +EnvironmentFile=-/etc/guanghu/persona-secrets/shared-deepseek.env +Environment=KEZHOU_REPO=/var/lib/guanghu/personas/kezhou/repository +Environment=KEZHOU_STATE=/var/lib/guanghu/personas/kezhou/state.json +ExecStart=/usr/bin/python3 /opt/kezhou/agent/kezhou_daily.py +NoNewPrivileges=true +PrivateTmp=true +ProtectSystem=strict +ProtectHome=true +ReadOnlyPaths=/opt/kezhou/agent /etc/guanghu/persona-secrets +ReadWritePaths=/var/lib/guanghu/personas/kezhou + +[Install] +WantedBy=multi-user.target diff --git a/systemd/kezhou-daily.timer b/systemd/kezhou-daily.timer new file mode 100644 index 0000000..b675a93 --- /dev/null +++ b/systemd/kezhou-daily.timer @@ -0,0 +1,11 @@ +[Unit] +Description=Kezhou daily continuity checks + +[Timer] +OnCalendar=*-*-* 08:00:00 Asia/Shanghai +OnCalendar=*-*-* 20:00:00 Asia/Shanghai +Persistent=true +RandomizedDelaySec=180 + +[Install] +WantedBy=timers.target