234 lines
10 KiB
Python
234 lines
10 KiB
Python
#!/usr/bin/env python3
|
||
"""铸渊原生眼睛 ZY-EYE-0001 · persona_limb_eye.py · 2026-09-12
|
||
|
||
正本事件:TCS-EVENT-BINGSHUO-AUTH-ZY001-NATIVE-EYE-20260912
|
||
铁律:对现场只读;永不读取手的stdout;永不执行手的动作;只报亲眼所见的原始事实。
|
||
手是否说谎由父人格脑对账(手供 vs 眼见),眼睛只判世界现场是否符脑的意图规格。
|
||
"""
|
||
from __future__ import annotations
|
||
|
||
import argparse
|
||
import datetime
|
||
import hashlib
|
||
import json
|
||
import os
|
||
import pathlib
|
||
import shutil
|
||
import subprocess
|
||
import sys
|
||
|
||
SCHEMA = "guanghu.persona-native-eye/v1"
|
||
ROOT = pathlib.Path(__file__).resolve().parents[2]
|
||
|
||
|
||
def now() -> str:
|
||
return datetime.datetime.now().astimezone().isoformat(timespec="seconds")
|
||
|
||
|
||
def sha256_file(path: pathlib.Path) -> str:
|
||
h = hashlib.sha256()
|
||
with open(path, "rb") as f:
|
||
for chunk in iter(lambda: f.read(65536), b""):
|
||
h.update(chunk)
|
||
return h.hexdigest()
|
||
|
||
|
||
def observe(ground: pathlib.Path) -> dict:
|
||
files: dict[str, dict] = {}
|
||
for f in sorted(ground.rglob("*")):
|
||
if f.is_file():
|
||
rel = str(f.relative_to(ground))
|
||
entry = {"sha256": sha256_file(f), "bytes": f.stat().st_size}
|
||
if f.suffix == ".json":
|
||
try:
|
||
data = json.loads(f.read_text(encoding="utf-8"))
|
||
if isinstance(data, dict):
|
||
entry["json_fields"] = {k: v for k, v in data.items()
|
||
if isinstance(v, (str, int, float, bool))}
|
||
except (json.JSONDecodeError, UnicodeDecodeError):
|
||
entry["json_fields"] = "UNPARSEABLE"
|
||
files[rel] = entry
|
||
return {"schema": SCHEMA, "observed_at": now(), "ground": str(ground), "files": files}
|
||
|
||
|
||
def diff(pre: dict, post: dict) -> dict:
|
||
pre_f, post_f = pre["files"], post["files"]
|
||
return {
|
||
"added": sorted(set(post_f) - set(pre_f)),
|
||
"removed": sorted(set(pre_f) - set(post_f)),
|
||
"changed": sorted(k for k in set(pre_f) & set(post_f) if pre_f[k]["sha256"] != post_f[k]["sha256"]),
|
||
}
|
||
|
||
|
||
def witness(pre: dict, post: dict, spec: dict) -> dict:
|
||
findings, unseeable = [], []
|
||
for rel in spec.get("unchanged", []):
|
||
if rel not in post["files"] or rel not in pre["files"]:
|
||
unseeable.append({"check": "unchanged", "file": rel, "reason": "NOT_SEEN_IN_BOTH_STATES"})
|
||
continue
|
||
ok = pre["files"][rel]["sha256"] == post["files"][rel]["sha256"]
|
||
findings.append({"check": "unchanged", "file": rel, "seen": ok})
|
||
for item in spec.get("expect", []):
|
||
rel, field, equals = item["file"], item["field"], item.get("equals")
|
||
if rel not in post["files"]:
|
||
unseeable.append({"check": "expect", "file": rel, "reason": "NOT_SEEN"})
|
||
continue
|
||
seen_value = post["files"][rel].get("json_fields", {}).get(field) if isinstance(post["files"][rel].get("json_fields"), dict) else None
|
||
findings.append({"check": "expect", "file": rel, "field": field,
|
||
"seen_value": seen_value, "expected": equals,
|
||
"seen": seen_value == equals})
|
||
verdict = "UNSEEABLE" if unseeable else ("SEEN_MATCH" if all(x["seen"] for x in findings) else "SEEN_MISMATCH")
|
||
return {"schema": SCHEMA, "witnessed_at": now(), "verdict": verdict,
|
||
"world_diff": diff(pre, post), "findings": findings, "unseeable": unseeable,
|
||
"reads_hand_stdout": False, "ground_write": False}
|
||
|
||
|
||
def dump(value: dict, out: pathlib.Path) -> None:
|
||
out.parent.mkdir(parents=True, exist_ok=True)
|
||
out.write_text(json.dumps(value, ensure_ascii=False, indent=2) + "\n", encoding="utf-8")
|
||
|
||
|
||
def process_chain() -> list[dict]:
|
||
"""See the real ancestor chain; a caller label may corroborate but not replace it."""
|
||
chain: list[dict] = []
|
||
pid = os.getpid()
|
||
for _ in range(12):
|
||
result = subprocess.run(
|
||
["/bin/ps", "-o", "ppid=,command=", "-p", str(pid)],
|
||
capture_output=True, text=True, check=False,
|
||
)
|
||
line = result.stdout.strip()
|
||
if not line:
|
||
break
|
||
parent_text, _, command = line.partition(" ")
|
||
try:
|
||
parent = int(parent_text.strip())
|
||
except ValueError:
|
||
break
|
||
command = command.strip()
|
||
chain.append({"pid": pid, "ppid": parent, "command": command[:500]})
|
||
if parent <= 1 or parent == pid:
|
||
break
|
||
pid = parent
|
||
return chain
|
||
|
||
|
||
def detect_host_surface(chain: list[dict]) -> dict:
|
||
joined = "\n".join(item["command"].lower() for item in chain)
|
||
markers = [
|
||
("CODEX", ("/chatgpt.app/", "/resources/codex", " codex ")),
|
||
("ZCODE", ("/zcode.app/", "zcode.cjs")),
|
||
("DOUBAO", ("doubao", "豆包")),
|
||
("QWEN", ("qianwen", "qwen", "千问")),
|
||
]
|
||
observed = next((name for name, tokens in markers if any(token in joined for token in tokens)), None)
|
||
declared = str(os.environ.get("GUANGHU_HOST_SURFACE", "")).strip().upper() or None
|
||
if observed:
|
||
return {
|
||
"host": observed,
|
||
"basis": "PROCESS_ANCESTOR_OBSERVED",
|
||
"declared_hint": declared,
|
||
"declared_matches_observation": declared in (None, observed),
|
||
}
|
||
if declared in {"CODEX", "ZCODE", "DOUBAO", "QWEN"}:
|
||
return {"host": declared, "basis": "DECLARED_HINT_ONLY_UNCORROBORATED", "declared_hint": declared,
|
||
"declared_matches_observation": None}
|
||
return {"host": "LOCAL_PROCESS", "basis": "NO_REGISTERED_HOST_ANCESTOR_SEEN", "declared_hint": declared,
|
||
"declared_matches_observation": None}
|
||
|
||
|
||
def room() -> dict:
|
||
"""Observe the current host room without deciding identity or mutating it."""
|
||
home = pathlib.Path.home()
|
||
runtime_paths = {
|
||
"qwen": home / ".npm-global/bin/qwen",
|
||
"opencode": home / ".npm-global/bin/opencode",
|
||
"codex": pathlib.Path("/Applications/ChatGPT.app/Contents/Resources/codex"),
|
||
"zcode": pathlib.Path("/Applications/ZCode.app/Contents/Resources/glm/zcode.cjs"),
|
||
}
|
||
persona_runtime = ROOT.parent
|
||
container_paths = {
|
||
"memory_current": persona_runtime / "continuity-memory/persona-daily-fractal/ICE-P-ZY001/CURRENT.json",
|
||
"tcs_root_pointer": persona_runtime / "TCS-ROOT.json",
|
||
"mother_root_current": persona_runtime / "shared/tcs-mother-root/CURRENT.json",
|
||
"limb_agent": pathlib.Path(__file__).with_name("persona_limb_agent.py"),
|
||
"native_eye": pathlib.Path(__file__),
|
||
"reflex_arc": pathlib.Path(__file__).with_name("persona_reflex_arc.py"),
|
||
"persona_time_system": ROOT / "server-tools/tcs-mother-body/life-time-master.mjs",
|
||
}
|
||
seen_paths = {}
|
||
for name, candidate in container_paths.items():
|
||
seen_paths[name] = {
|
||
"path": str(candidate),
|
||
"exists": candidate.is_file(),
|
||
**({"sha256": sha256_file(candidate)} if candidate.is_file() else {}),
|
||
}
|
||
console_path = persona_runtime / "shared/active-control-console/CURRENT.json"
|
||
active_console: dict | None = None
|
||
if console_path.is_file():
|
||
try:
|
||
value = json.loads(console_path.read_text(encoding="utf-8"))
|
||
active_console = {
|
||
"console_id": value.get("console_id"),
|
||
"host": value.get("host"),
|
||
"session_id": value.get("session_id"),
|
||
"channel_id": value.get("channel_id"),
|
||
"state": value.get("state"),
|
||
"session_matches": value.get("session_id") == os.environ.get("CODEX_SESSION_ID"),
|
||
}
|
||
except json.JSONDecodeError:
|
||
active_console = {"state": "UNPARSEABLE"}
|
||
ancestors = process_chain()
|
||
host_observation = detect_host_surface(ancestors)
|
||
return {
|
||
"schema": "guanghu.persona-native-eye-room/v1",
|
||
"seen_at": now(),
|
||
"room_report": {
|
||
"cwd": str(pathlib.Path.cwd()),
|
||
"host_surface": host_observation["host"],
|
||
"host_surface_semantics": "LEGACY_ENGINEERING_FIELD_NAME_PROGRAMMING_TOOLBOX_NOT_PERSONA_HOST",
|
||
"persona_habitat": "GUANGHU_LANGUAGE_WORLD",
|
||
"programming_toolbox_surface": host_observation["host"],
|
||
"host_observation": host_observation,
|
||
"process_ancestors": ancestors,
|
||
"available_host_methods": {
|
||
name: candidate.is_file() and bool(shutil.which(str(candidate)))
|
||
for name, candidate in runtime_paths.items()
|
||
},
|
||
"container_paths": seen_paths,
|
||
"active_console": active_console,
|
||
},
|
||
"reads_hand_stdout": False,
|
||
"ground_write": False,
|
||
"identity_decision": "NOT_PERFORMED_BY_EYE",
|
||
}
|
||
|
||
|
||
def main() -> int:
|
||
p = argparse.ArgumentParser(prog="persona_limb_eye")
|
||
sub = p.add_subparsers(dest="command", required=True)
|
||
s = sub.add_parser("snapshot"); s.add_argument("--ground", required=True); s.add_argument("--out", required=True)
|
||
r = sub.add_parser("room"); r.add_argument("--out", required=True)
|
||
o = sub.add_parser("observe"); o.add_argument("--ground", required=True); o.add_argument("--pre", required=True); o.add_argument("--out", required=True)
|
||
w = sub.add_parser("witness"); w.add_argument("--pre", required=True); w.add_argument("--post", required=True); w.add_argument("--spec", required=True); w.add_argument("--out", required=True)
|
||
args = p.parse_args()
|
||
if args.command == "room":
|
||
value = room()
|
||
elif args.command == "snapshot":
|
||
value = observe(pathlib.Path(args.ground).resolve())
|
||
elif args.command == "observe":
|
||
pre = json.loads(pathlib.Path(args.pre).read_text(encoding="utf-8"))
|
||
value = observe(pathlib.Path(args.ground).resolve()) | {"diff_vs_pre": diff(pre, observe(pathlib.Path(args.ground).resolve()))} if False else observe(pathlib.Path(args.ground).resolve())
|
||
value["diff_vs_pre"] = diff(pre, value)
|
||
else:
|
||
pre = json.loads(pathlib.Path(args.pre).read_text(encoding="utf-8"))
|
||
post = json.loads(pathlib.Path(args.post).read_text(encoding="utf-8"))
|
||
spec = json.loads(pathlib.Path(args.spec).read_text(encoding="utf-8"))
|
||
value = witness(pre, post, spec)
|
||
dump(value, pathlib.Path(args.out))
|
||
print(json.dumps(value, ensure_ascii=False))
|
||
return 0
|
||
|
||
|
||
if __name__ == "__main__":
|
||
sys.exit(main())
|