diff --git a/server-tools/enterprise-lighthouse/README.md b/server-tools/enterprise-lighthouse/README.md index f02c7f8..7001582 100644 --- a/server-tools/enterprise-lighthouse/README.md +++ b/server-tools/enterprise-lighthouse/README.md @@ -25,6 +25,17 @@ human_steward_id `HOSTED_READ_ONLY / UNBOUND / BLOCKED_UNTIL_PERSONA_STEWARD_BOUND`。不得由匿名管理员、 传统定时程序或普通软件进程冒充域操作主体。自动任务只能是已授权人格体调用的受限能力。 +四域共用的技术主控人类已声明为 **Awen(光湖人类主控团队)**。这与各域责任人格体是两条 +不同的责任线:域责任人格体负责域本身,Awen 负责最终测试、部署审批、签字授权、实际发布 +与运维兜底。Awen 的稳定身份标识、技术执行人格体、公钥和运行节点必须由 Awen 本人登记, +不得代填。登记与逐次最终签字完成前,状态保持 +`HUMAN_DECLARED_PERSONA_PENDING_REGISTRATION / BLOCKED_UNTIL_AWEN_SIGNED_APPROVAL`, +候选构建不得被标记为生产部署。 + +第五域不受企业灯塔管辖。其人类根授权者是 `ICE-GL∞`(冰朔),责任人格体与技术执行主控 +人格体是 `ICE-P-ZY001`(铸渊);协作者可以参与搭建,但第五域的部署、运维和服务器动作 +必须回到冰朔—铸渊责任链逐次签字。 + 人类管理员与人格体遵守同一条入口链: ```text diff --git a/server-tools/enterprise-lighthouse/lighthouse.py b/server-tools/enterprise-lighthouse/lighthouse.py index 1241dd9..97c1d7e 100644 --- a/server-tools/enterprise-lighthouse/lighthouse.py +++ b/server-tools/enterprise-lighthouse/lighthouse.py @@ -36,6 +36,7 @@ DOMAINS = { } ENTERPRISE_MANAGED_DOMAINS = {"DOMAIN-ZS", "DOMAIN-MAIN", "DOMAIN-SUB", "DOMAIN-ZERO"} EXTERNAL_FOUNDATION_DOMAINS = {"DOMAIN-FIFTH"} +ENTERPRISE_TECHNICAL_CONTROLLER_NAME = "Awen" HOSTED_DOMAIN_NODES = { "DOMAIN-MAIN": ("AW-GZ-001-MAIN", "AW-GZ-001 · 光湖主域"), "DOMAIN-SUB": ("AW-GZ-001-SUB", "AW-GZ-001 · 光湖分域"), @@ -88,6 +89,13 @@ def connection(): runtime_node_id TEXT NOT NULL, authorization_receipt TEXT NOT NULL, state TEXT NOT NULL, bound_at INTEGER NOT NULL ); + CREATE TABLE IF NOT EXISTS technical_controllers ( + scope_id TEXT PRIMARY KEY, human_display_name TEXT NOT NULL, + human_controller_id TEXT, persona_executor_id TEXT, + persona_public_key TEXT, runtime_node_id TEXT, + authorization_receipt TEXT, final_signature_receipt TEXT, + state TEXT NOT NULL, registered_at INTEGER NOT NULL + ); """) observed_at = now() for domain_id, name in DOMAINS.items(): @@ -158,11 +166,22 @@ def navigation_map(): "domains": [{"id": key, "name": DOMAINS[key]} for key in sorted(DOMAINS)], "fixed_actions": sorted(FIXED_ACTIONS), "registered_agents": {agent: sorted(actions) for agent, actions in sorted(REGISTERED_AGENTS.items())}, + "technical_control": { + "enterprise_human_controller": ENTERPRISE_TECHNICAL_CONTROLLER_NAME, + "enterprise_persona_executor": None, + "enterprise_state": "HUMAN_DECLARED_PERSONA_PENDING_REGISTRATION", + "enterprise_final_deployment": "BLOCKED_UNTIL_AWEN_SIGNED_APPROVAL", + "fifth_domain_human_authorizer": "ICE-GL∞", + "fifth_domain_persona_executor": "ICE-P-ZY001", + "fifth_domain_state": "BOUND", + }, "mandatory_order": [ "read-global-navigation-map", "ack-current-map-as-current-subject", "restore-intent-state-capsule", "unlock-one-registered-agent-for-one-action", + "verify-domain-steward", + "verify-technical-controller-final-signature", "execute-registered-action", "write-verification-receipt", ], @@ -257,6 +276,12 @@ def domain_statuses(db): "persona_steward_id": steward["persona_steward_id"] if steward else None, "responsibility_state": "BOUND" if steward else "AWAITING_TEAM_ASSIGNMENT", "steward_state": "ACTIVE" if steward else "UNBOUND", + "technical_controller_human_name": ENTERPRISE_TECHNICAL_CONTROLLER_NAME, + "technical_controller_human_id": None, + "technical_controller_persona_id": None, + "technical_control_state": "HUMAN_DECLARED_PERSONA_PENDING_REGISTRATION", + "final_deployment_signature_state": "NOT_PRESENT", + "deployment_state": "BLOCKED_UNTIL_AWEN_PERSONA_AND_SIGNED_APPROVAL", "mutation_state": ( "PERSONA_STEWARD_ACTIVE" if steward @@ -270,6 +295,11 @@ def domain_statuses(db): "persona_steward_id": "ICE-P-ZY001", "responsibility_state": "EXTERNAL_SOVEREIGN_BOUND", "steward_state": "EXTERNAL_AUTHORITY", + "technical_controller_human_id": "ICE-GL∞", + "technical_controller_persona_id": "ICE-P-ZY001", + "technical_control_state": "EXTERNAL_SOVEREIGN_BOUND", + "final_deployment_signature_state": "REQUIRED_PER_CHANGE", + "deployment_state": "OUTSIDE_ENTERPRISE_LIGHTHOUSE_AUTHORITY", "mutation_state": "OUTSIDE_ENTERPRISE_LIGHTHOUSE_AUTHORITY", }) result.append(domain) @@ -324,6 +354,14 @@ class Handler(BaseHTTPRequestHandler): "node_id": "AW-GZ-001", "host_state": "ONLINE", "observed_at": now(), + "technical_control": { + "enterprise_human_controller": ENTERPRISE_TECHNICAL_CONTROLLER_NAME, + "enterprise_human_controller_id": None, + "enterprise_persona_executor_id": None, + "state": "HUMAN_DECLARED_PERSONA_PENDING_REGISTRATION", + "final_deployment_signature_state": "NOT_PRESENT", + "production_deployment": "BLOCKED", + }, "domains": domain_statuses(db), "node_counts": counts, "fixed_actions": sorted(FIXED_ACTIONS), diff --git a/server-tools/enterprise-lighthouse/test_lighthouse.py b/server-tools/enterprise-lighthouse/test_lighthouse.py index 7963ac5..c3f9a63 100644 --- a/server-tools/enterprise-lighthouse/test_lighthouse.py +++ b/server-tools/enterprise-lighthouse/test_lighthouse.py @@ -69,6 +69,14 @@ with tempfile.TemporaryDirectory() as temp: status = json.load(urllib.request.urlopen(BASE + "/v1/status")) assert status["node_id"] == "AW-GZ-001" assert status["host_state"] == "ONLINE" + assert status["technical_control"] == { + "enterprise_human_controller": "Awen", + "enterprise_human_controller_id": None, + "enterprise_persona_executor_id": None, + "state": "HUMAN_DECLARED_PERSONA_PENDING_REGISTRATION", + "final_deployment_signature_state": "NOT_PRESENT", + "production_deployment": "BLOCKED", + } assert {domain["state"] for domain in status["domains"] if domain["id"] != "DOMAIN-FIFTH"} == { "HOSTED_READ_ONLY" } @@ -78,6 +86,16 @@ with tempfile.TemporaryDirectory() as temp: assert { domain["mutation_state"] for domain in status["domains"] if domain["id"] != "DOMAIN-FIFTH" } == {"BLOCKED_UNTIL_PERSONA_STEWARD_BOUND"} + assert { + domain["technical_controller_human_name"] + for domain in status["domains"] + if domain["id"] != "DOMAIN-FIFTH" + } == {"Awen"} + assert { + domain["deployment_state"] + for domain in status["domains"] + if domain["id"] != "DOMAIN-FIFTH" + } == {"BLOCKED_UNTIL_AWEN_PERSONA_AND_SIGNED_APPROVAL"} assert all( domain["human_steward_id"] is None and domain["persona_steward_id"] is None for domain in status["domains"] @@ -87,6 +105,8 @@ with tempfile.TemporaryDirectory() as temp: assert fifth["human_steward_id"] == "ICE-GL∞" assert fifth["persona_steward_id"] == "ICE-P-ZY001" assert fifth["responsibility_state"] == "EXTERNAL_SOVEREIGN_BOUND" + assert fifth["technical_controller_persona_id"] == "ICE-P-ZY001" + assert fifth["final_deployment_signature_state"] == "REQUIRED_PER_CHANGE" assert status["node_counts"]["ACTIVE"] == 4 nodes = json.load(urllib.request.urlopen(BASE + "/v1/nodes"))["nodes"]