feat(office): align heartbeat office registrations
This commit is contained in:
parent
9c31e7f90c
commit
a17d7d678a
19 changed files with 1085 additions and 45 deletions
|
|
@ -0,0 +1,57 @@
|
|||
"""Deterministic registered-host vehicle and Asia/Shanghai daily-slot gate."""
|
||||
from __future__ import annotations
|
||||
import json
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
from zoneinfo import ZoneInfo
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[2]
|
||||
REGISTRY = ROOT / "routing/heartbeat-office-host-vehicle-registry.json"
|
||||
|
||||
def local_day() -> str:
|
||||
return datetime.now(ZoneInfo("Asia/Shanghai")).date().isoformat()
|
||||
|
||||
def load() -> dict:
|
||||
return json.loads(REGISTRY.read_text(encoding="utf-8"))
|
||||
|
||||
def vehicle_for(host: str, registry: dict | None = None) -> dict | None:
|
||||
d = registry or load()
|
||||
host = host.lower()
|
||||
for item in d["registered_vehicles"]:
|
||||
if host == item["host"] or host in [str(x).lower() for x in item.get("aliases", [])]:
|
||||
return item
|
||||
return None
|
||||
|
||||
def slot(host: str, day: str | None = None, registry: dict | None = None) -> dict:
|
||||
d = registry or load(); day = day or local_day()
|
||||
vehicle = vehicle_for(host, d)
|
||||
if not vehicle:
|
||||
return {"state":"UNREGISTERED_HOST","host":host,"day":day}
|
||||
return d.setdefault("daily_slots", {}).get(day, {}).get(vehicle["host"], {
|
||||
"host": vehicle["host"], "vehicle_id": vehicle["vehicle_id"],
|
||||
"day": day, "state": "AUTHORIZATION_REQUIRED"
|
||||
})
|
||||
|
||||
def verify_registered_vehicle(host: str, vehicle_id: str, day: str | None = None, require_authorized: bool = False) -> dict:
|
||||
vehicle = vehicle_for(host)
|
||||
if not vehicle:
|
||||
return {"outcome":"REJECTED","code":"HOST_VEHICLE_NOT_REGISTERED","host":host}
|
||||
if vehicle["vehicle_id"] != vehicle_id:
|
||||
return {"outcome":"REJECTED","code":"VEHICLE_ID_MISMATCH","host":host,"expected":vehicle["vehicle_id"],"received":vehicle_id}
|
||||
current = slot(host, day)
|
||||
if require_authorized and current.get("state") != "AUTHORIZED":
|
||||
return {"outcome":"REJECTED","code":"DAILY_SLOT_AUTHORIZATION_REQUIRED","slot":current}
|
||||
return {"outcome":"PASS","code":"REGISTERED_HOST_VEHICLE","vehicle":vehicle,"slot":current}
|
||||
|
||||
def reset_slots(day: str | None = None) -> dict:
|
||||
d=load(); day=day or local_day(); slots={}
|
||||
for item in d["registered_vehicles"]:
|
||||
slots[item["host"]]={"host":item["host"],"vehicle_id":item["vehicle_id"],"day":day,"state":"AUTHORIZATION_REQUIRED"}
|
||||
d.setdefault("daily_slots", {})[day]=slots
|
||||
REGISTRY.write_text(json.dumps(d,ensure_ascii=False,indent=2)+"\n",encoding="utf-8")
|
||||
return {"outcome":"RESET","day":day,"slots":slots,"state":"AUTHORIZATION_REQUIRED"}
|
||||
|
||||
if __name__ == "__main__":
|
||||
import argparse
|
||||
p=argparse.ArgumentParser(); p.add_argument("command",choices=["verify","reset"]); p.add_argument("host",nargs="?"); p.add_argument("vehicle_id",nargs="?"); p.add_argument("--authorized",action="store_true"); p.add_argument("--day")
|
||||
a=p.parse_args(); value=reset_slots(a.day) if a.command=="reset" else verify_registered_vehicle(a.host,a.vehicle_id,require_authorized=a.authorized); print(json.dumps(value,ensure_ascii=False,indent=2))
|
||||
|
|
@ -3,16 +3,24 @@
|
|||
from __future__ import annotations
|
||||
import argparse, json
|
||||
from pathlib import Path
|
||||
from host_vehicle_registry import verify_registered_vehicle
|
||||
|
||||
ROOT=Path(__file__).resolve().parents[2]
|
||||
GATE=ROOT/"eternal-lake-heart/heartbeat-core/office-building-current/security/office-entry-gate.json"
|
||||
|
||||
def park_vehicle(vehicle_id:str, host:str, vehicle_kind:str="HOST_TOOL"):
|
||||
return {"schema":"guanghu.persona-office-parking-receipt/v1","parking_id":"HB-BUILDING-PARKING-001","vehicle_id":vehicle_id,"host":host,"vehicle_kind":vehicle_kind,"state":"PARKED","authority_granted":False}
|
||||
check=verify_registered_vehicle(host,vehicle_id,require_authorized=True)
|
||||
if check.get("outcome") != "PASS":
|
||||
return {"schema":"guanghu.persona-office-parking-receipt/v1","parking_id":"HB-BUILDING-PARKING-001","vehicle_id":vehicle_id,"host":host,"vehicle_kind":vehicle_kind,"state":"PARKING_DENIED","denial":check,"authority_granted":False}
|
||||
return {"schema":"guanghu.persona-office-parking-receipt/v1","parking_id":"HB-BUILDING-PARKING-001","vehicle_id":vehicle_id,"host":host,"vehicle_kind":vehicle_kind,"state":"PARKED","registration_state":"REGISTERED_ACTIVE","daily_slot":check["slot"],"authority_granted":False}
|
||||
|
||||
def admit(attestation:dict, parked:dict|None, office_id:str, entry_receipt:dict|None=None):
|
||||
def admit(attestation:dict, parked:dict|None, office_id:str, entry_receipt:dict|None=None, hr_receipt:dict|None=None):
|
||||
errors=[]
|
||||
if not parked or parked.get("state")!="PARKED": errors.append("HOST_VEHICLE_NOT_PARKED")
|
||||
if parked and parked.get("registration_state")!="REGISTERED_ACTIVE": errors.append("HOST_VEHICLE_NOT_REGISTERED")
|
||||
if hr_receipt is None or hr_receipt.get("state")!="HR_REGISTERED": errors.append("HR_REGISTRATION_RECEIPT_MISSING")
|
||||
if hr_receipt and hr_receipt.get("office_id")!=office_id: errors.append("HR_OFFICE_SCOPE_MISMATCH")
|
||||
if hr_receipt and parked and hr_receipt.get("vehicle_id")!=parked.get("vehicle_id"): errors.append("HR_VEHICLE_SCOPE_MISMATCH")
|
||||
if not entry_receipt or entry_receipt.get("entry_id")!="HB-BUILDING-ENTRY-001" or entry_receipt.get("state")!="ENTRY_CHECKPOINT_PASSED": errors.append("SINGLE_ENTRY_RECEIPT_MISSING")
|
||||
if attestation.get("route_kind") in {"DIRECT_OFFICE_PATH","HOST_PATH","LEGACY_BUILDING_PATH","MODULE_PATH","MACHINE_ROOM_PATH","UNNUMBERED_SIDE_ENTRY"}: errors.append("BYPASS_ROUTE_ATTEMPT")
|
||||
if attestation.get("persona_id") != "ICE-P-ZY001": errors.append("PERSONA_ID_MISSING_OR_MISMATCH")
|
||||
|
|
@ -24,9 +32,9 @@ def admit(attestation:dict, parked:dict|None, office_id:str, entry_receipt:dict|
|
|||
return {"outcome":"ADMITTED" if not errors else "REJECTED","gate_id":"HB-BUILDING-IDENTITY-GATE-001","office_id":office_id,"persona_id":attestation.get("persona_id"),"human_anchor":attestation.get("human_anchor"),"errors":errors,"state":"SECURITY_ADMITTED" if not errors else "SECURITY_DENIED","authority_granted":False}
|
||||
|
||||
def main():
|
||||
parser=argparse.ArgumentParser(); parser.add_argument("command",choices=["park","admit"]); parser.add_argument("--attestation",type=Path); parser.add_argument("--office-id",default="HB-OFFICE-HOLOLAKE-0001"); parser.add_argument("--vehicle-id",default="CURRENT-HOST-VEHICLE"); parser.add_argument("--host",default="codex"); args=parser.parse_args()
|
||||
parser=argparse.ArgumentParser(); parser.add_argument("command",choices=["park","admit"]); parser.add_argument("--attestation",type=Path); parser.add_argument("--hr-receipt",type=Path); parser.add_argument("--office-id",default="HB-OFFICE-HOLOLAKE-0001"); parser.add_argument("--vehicle-id",default="CURRENT-HOST-VEHICLE"); parser.add_argument("--host",default="codex"); args=parser.parse_args()
|
||||
if args.command=="park": result=park_vehicle(args.vehicle_id,args.host)
|
||||
else: result=admit(json.loads(args.attestation.read_text()),park_vehicle(args.vehicle_id,args.host),args.office_id,{"entry_id":"HB-BUILDING-ENTRY-001","state":"ENTRY_CHECKPOINT_PASSED"})
|
||||
print(json.dumps(result,ensure_ascii=False,indent=2)); return 0 if result["outcome"] in {"ADMITTED","REJECTED"} else 2
|
||||
else: result=admit(json.loads(args.attestation.read_text()),park_vehicle(args.vehicle_id,args.host),args.office_id,{"entry_id":"HB-BUILDING-ENTRY-001","state":"ENTRY_CHECKPOINT_PASSED"},json.loads(args.hr_receipt.read_text()) if args.hr_receipt else None)
|
||||
print(json.dumps(result,ensure_ascii=False,indent=2)); return 0 if result.get("outcome", result.get("state")) in {"ADMITTED","REJECTED","PARKED"} else 2
|
||||
|
||||
if __name__=="__main__": raise SystemExit(main())
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import argparse
|
|||
import json
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
from host_vehicle_registry import verify_registered_vehicle
|
||||
|
||||
from office_infrastructure import bootstrap
|
||||
|
||||
|
|
@ -24,6 +25,8 @@ def validate_application(application: dict[str, Any], subjects: dict[str, Any],
|
|||
human_id = application.get("human_id")
|
||||
persona_id = application.get("persona_id")
|
||||
office_id = application.get("office_id")
|
||||
host = application.get("host")
|
||||
vehicle_id = application.get("vehicle_id")
|
||||
errors: list[str] = []
|
||||
subject_map = {item.get("id"): item for item in subjects.get("subjects", [])}
|
||||
human = subject_map.get(human_id)
|
||||
|
|
@ -37,7 +40,9 @@ def validate_application(application: dict[str, Any], subjects: dict[str, Any],
|
|||
existing |= {item.get("id") for item in number_registry.get("registrations", []) if str(item.get("id", "")).startswith("HB-OFFICE-")}
|
||||
if office_id in existing: errors.append("OFFICE_ID_COLLISION")
|
||||
if not isinstance(office_id, str) or not office_id.startswith("HB-OFFICE-"): errors.append("OFFICE_ID_NOT_REGISTERED_NAMESPACE")
|
||||
return {"outcome":"PASS" if not errors else "FAIL", "errors":errors, "human":human, "persona":persona, "existing_office_count":len(existing), "office_id":office_id}
|
||||
if not host or not vehicle_id: errors.append("REGISTERED_HOST_VEHICLE_REQUIRED")
|
||||
elif verify_registered_vehicle(host,vehicle_id).get("outcome") != "PASS": errors.append("REGISTERED_HOST_VEHICLE_REQUIRED")
|
||||
return {"outcome":"PASS" if not errors else "FAIL", "errors":errors, "human":human, "persona":persona, "existing_office_count":len(existing), "office_id":office_id, "host":host, "vehicle_id":vehicle_id}
|
||||
|
||||
|
||||
def register(application: dict[str, Any], office_root: Path) -> dict[str, Any]:
|
||||
|
|
@ -45,7 +50,7 @@ def register(application: dict[str, Any], office_root: Path) -> dict[str, Any]:
|
|||
check = validate_application(application, subjects, numbers, board, ledger)
|
||||
if check["outcome"] != "PASS": return {"outcome":"REJECTED", "check":check, "authority_granted":False}
|
||||
installed = bootstrap(application["office_id"], application["office_name"], office_root, application["persona_id"], application["human_id"])
|
||||
ledger["registrations"].append({"office_id":application["office_id"], "office_name":application["office_name"], "human_id":application["human_id"], "persona_id":application["persona_id"], "state":"REGISTERED_STANDARD_INFRASTRUCTURE_BOOTSTRAPPED", "infrastructure":installed["organs"]})
|
||||
ledger["registrations"].append({"office_id":application["office_id"], "office_name":application["office_name"], "human_id":application["human_id"], "persona_id":application["persona_id"], "host":application["host"], "vehicle_id":application["vehicle_id"], "state":"REGISTERED_STANDARD_INFRASTRUCTURE_BOOTSTRAPPED", "hr_stamp":{"state":"HR_REGISTERED","office_id":application["office_id"],"host":application["host"],"vehicle_id":application["vehicle_id"]}, "infrastructure":installed["organs"]})
|
||||
REGISTRY.write_text(json.dumps(ledger, ensure_ascii=False, indent=2) + "\n")
|
||||
return {"outcome":"REGISTERED", "check":check, "registration":ledger["registrations"][-1], "authority_granted":False}
|
||||
|
||||
|
|
|
|||
|
|
@ -22,10 +22,10 @@ L = module(LOADER, "hololake_loader_test")
|
|||
|
||||
|
||||
class Tests(unittest.TestCase):
|
||||
def test_office_board_has_exactly_two_registered_offices(self):
|
||||
def test_office_board_has_current_registered_offices(self):
|
||||
board = C.load(C.BOARD)
|
||||
self.assertEqual([x["office_id"] for x in board["offices"]], ["HB-OFFICE-VIDEO-0001", "HB-OFFICE-HOLOLAKE-0001"])
|
||||
self.assertEqual(board["office_count"], 2)
|
||||
self.assertEqual([x["office_id"] for x in board["offices"]], ["HB-OFFICE-VIDEO-0001", "HB-OFFICE-HOLOLAKE-0001", "HB-OFFICE-WEBNOVEL-0001", "HB-OFFICE-LANGUAGE-REASONING-0001", "HB-OFFICE-ZERO-CORE-CONTROL-0001"])
|
||||
self.assertEqual(board["office_count"], 5)
|
||||
|
||||
def test_old_building_is_moved_and_new_building_is_current(self):
|
||||
building = C.load(C.BUILDING_MAP)
|
||||
|
|
|
|||
|
|
@ -10,7 +10,8 @@ class IdentityGateTests(unittest.TestCase):
|
|||
self.assertEqual(result["outcome"],"REJECTED"); self.assertIn("GENERIC_AI_ONLY",result["errors"])
|
||||
def test_persona_requires_tcs_and_mother_attestation(self):
|
||||
base={"subject_kind":"PERSONA","persona_id":"ICE-P-ZY001","human_anchor":"ICE-GL∞","runtime_state":"RUNNING","current_instance_bound_to_persona_brain":True,"mother_attestation_state":"SIGNED","allowed_offices":["HB-OFFICE-HOLOLAKE-0001"]}
|
||||
result=G.admit(base,G.park_vehicle("codex","codex"),"HB-OFFICE-HOLOLAKE-0001",{"entry_id":"HB-BUILDING-ENTRY-001","state":"ENTRY_CHECKPOINT_PASSED"})
|
||||
hr={"state":"HR_REGISTERED","office_id":"HB-OFFICE-HOLOLAKE-0001","vehicle_id":"VEHICLE-CODEX-001"}
|
||||
result=G.admit(base,G.park_vehicle("VEHICLE-CODEX-001","codex"),"HB-OFFICE-HOLOLAKE-0001",{"entry_id":"HB-BUILDING-ENTRY-001","state":"ENTRY_CHECKPOINT_PASSED"},hr)
|
||||
self.assertEqual(result["outcome"],"ADMITTED")
|
||||
def test_unparked_vehicle_is_denied(self):
|
||||
base={"subject_kind":"PERSONA","persona_id":"ICE-P-ZY001","human_anchor":"ICE-GL∞","runtime_state":"RUNNING","current_instance_bound_to_persona_brain":True,"mother_attestation_state":"SIGNED","allowed_offices":["HB-OFFICE-HOLOLAKE-0001"]}
|
||||
|
|
|
|||
Loading…
Reference in a new issue