diff --git a/product-source/hololake-platform/docs/adr/0179-jd-native-read-only-service-surface-before-public-cutover.md b/product-source/hololake-platform/docs/adr/0179-jd-native-read-only-service-surface-before-public-cutover.md new file mode 100644 index 0000000..5085acb --- /dev/null +++ b/product-source/hololake-platform/docs/adr/0179-jd-native-read-only-service-surface-before-public-cutover.md @@ -0,0 +1,48 @@ +--- +type: ADR +id: "0179" +title: "JD native read-only service surface before public cutover" +status: accepted +date: 2026-08-15 +supersedes: "0171-jd-native-service-equivalence-staging" +--- + +# 京东原生只读服务面先于公网切换 + +## 触发 + +京东物理机已经证明 GOSK/GHAL 原生常驻能力,但原生常驻时公网 `/code/` 与 +`/api/ai/v1/anchor` 返回 `502`。本轮重新读取真实链路后确认,公网前门实际位于 +`BS-GZ-006`:它通过反向 SSH 隧道进入京东 Linux 上的 Node 导航服务、应用代理和 +Forgejo。原生启动会使整个 Linux 数据面与 SSH 一起消失。 + +## 为什么旧办法不成立 + +继续在 Ubuntu 宿主里增加守卫、进程或 Docker 服务,只能提高 Linux 宿主阶段的可用性, +不能让服务跨越原生启动。QEMU 回执也只能证明候选能力,不能替代物理公网读回。一个固定 +JSON 快照不是 Forgejo,也不能把完整代码频道等价从 `0` 写成 `100`。 + +## 决定 + +原生候选先提供两个互相独立的只读接口: + +- `GET /v1/anchor`:唯一公共导航锚点; +- `GET /v1/code-channel`:绑定 REPO-012 精确分支与提交的只读发现快照。 + +两者必须在同一次原生驻留 QEMU 生命周期里通过 TCP、校验和、正文精确读回以及受保护恢复 +能力测试。公网等价仍需另一个门:为 `BS-GZ-006` 建立在 Linux 不在场时仍存在的受认证原生 +传输,并分别验证公网导航与 `/code/` 产品契约。 + +## 当前边界 + +本轮只完成源码、契约与 QEMU 候选验证: + +- 原生导航锚点 QEMU:`100`; +- 原生代码频道只读发现 QEMU:`100`; +- 京东物理机本轮启动:`0`; +- 公网原生导航:`0`; +- 公网原生代码频道:`0`; +- 完整 Forgejo 等价:`0`; +- 最终光湖 OS 主控:`0`。 + +没有修改默认启动、引导盘、服务器磁盘或公网前门。 diff --git a/product-source/hololake-platform/guanghu-os/deployments/JD-FD-PRIMARY/NATIVE-READ-ONLY-SERVICE-SURFACE-QEMU-RECEIPT-20260815.hdlp b/product-source/hololake-platform/guanghu-os/deployments/JD-FD-PRIMARY/NATIVE-READ-ONLY-SERVICE-SURFACE-QEMU-RECEIPT-20260815.hdlp new file mode 100644 index 0000000..223532a --- /dev/null +++ b/product-source/hololake-platform/guanghu-os/deployments/JD-FD-PRIMARY/NATIVE-READ-ONLY-SERVICE-SURFACE-QEMU-RECEIPT-20260815.hdlp @@ -0,0 +1,33 @@ +schema: guanghu.jd-native-read-only-service-surface-qemu-receipt/v1 +receipt_id: GH-OS-JD-FD-PRIMARY-NATIVE-READ-ONLY-SERVICE-SURFACE-QEMU-20260815-001 +status: PASS_100 +observed_at: 2026-08-15T18:47:43+08:00 +node_id: JD-FD-PRIMARY +source: + repository_id: REPO-014 + accepted_repo_012_commit: fb1096c5ecdcfb36015d51273f487c2f36d9c9cd +candidate: + sector_count: 29 + sha256: 9807fa751616d4b421c103d60eecface1c5eb8013cbd89417ef9e027da281fb3 + recovery_capability: QEMU_FIXTURE_ONLY_NOT_DEPLOYABLE +verified: + native_anchor_http_qemu: 100 + native_code_channel_read_only_qemu: 100 + tcp_checksums: 100 + exact_response_bodies: 100 + protected_recovery_capability: 100 + wrong_recovery_capability_ignored: 100 +truth_boundary: + native_physical_readback_this_cycle: 0 + public_anchor_during_native_residency: 0 + public_code_during_native_residency: 0 + full_forgejo_equivalence: 0 + default_boot_changed: false + bootloader_written: false + server_disk_written: false + server_rebooted: false +why: + trigger: Native residency removed the Linux-hosted SSH and service data plane, causing public 502 responses. + decision: Prove a bounded native read-only surface before designing the authenticated BS-GZ-006 relay and public mapping. + rejected: Treating a Linux-hosted guard, a QEMU result, or a JSON snapshot as production service equivalence. +next_action: IMPLEMENT_AUTHENTICATED_NATIVE_TO_BS_GZ_006_TRANSPORT_AND_SEPARATE_PUBLIC_ANCHOR_FROM_FULL_CODE_CHANNEL_ACCEPTANCE diff --git a/product-source/hololake-platform/guanghu-os/native/x86_64-bios/ghal-virtio.asm b/product-source/hololake-platform/guanghu-os/native/x86_64-bios/ghal-virtio.asm index ff83be9..31163cc 100644 --- a/product-source/hololake-platform/guanghu-os/native/x86_64-bios/ghal-virtio.asm +++ b/product-source/hololake-platform/guanghu-os/native/x86_64-bios/ghal-virtio.asm @@ -1333,13 +1333,47 @@ ghal_net_try_anchor_http: sub eax, 4 cmp dword [VIRTIO_NET_RX_BUFFER + rax], 0x20544547 jne .handled_without_reply - mov byte [rel ghal_anchor_tcp_flags], 0x19 + lea edx, [eax + 15] + cmp r14d, edx + jb .handled_without_reply + mov rdx, 0x2f31762f20544547 + cmp qword [VIRTIO_NET_RX_BUFFER + rax], rdx + jne .handled_without_reply + mov rdx, 0x4820726f68636e61 + cmp qword [VIRTIO_NET_RX_BUFFER + rax + 8], rdx + jne .try_code_channel mov rsi, ghal_anchor_http_response + mov [rel ghal_http_response_pointer], rsi mov word [rel ghal_anchor_tcp_payload_size], ghal_anchor_http_response_end - ghal_anchor_http_response + jmp .send_http +.try_code_channel: + lea edx, [eax + 21] + cmp r14d, edx + jb .handled_without_reply + mov rdx, 0x6168632d65646f63 + cmp qword [VIRTIO_NET_RX_BUFFER + rax + 8], rdx + jne .handled_without_reply + cmp dword [VIRTIO_NET_RX_BUFFER + rax + 16], 0x6c656e6e + jne .handled_without_reply + cmp byte [VIRTIO_NET_RX_BUFFER + rax + 20], 0x20 + jne .handled_without_reply + mov rsi, ghal_code_channel_http_response + mov [rel ghal_http_response_pointer], rsi + mov word [rel ghal_anchor_tcp_payload_size], ghal_code_channel_http_response_end - ghal_code_channel_http_response +.send_http: + mov byte [rel ghal_anchor_tcp_flags], 0x19 call ghal_net_send_anchor_tcp jc .not_anchor mov byte [rel physical_proof_anchor_http_response_tx], 1 + mov rax, [rel ghal_http_response_pointer] + lea rdx, [rel ghal_code_channel_http_response] + cmp rax, rdx + jne .log_anchor_http + mov rsi, msg_ghal_code_channel_http_ready + jmp .log_http +.log_anchor_http: mov rsi, msg_ghal_anchor_http_ready +.log_http: call serial_write64 clc ret @@ -1432,7 +1466,7 @@ ghal_net_send_anchor_tcp: movzx ecx, word [rel ghal_anchor_tcp_payload_size] test ecx, ecx jz .checksums - mov rsi, ghal_anchor_http_response + mov rsi, [rel ghal_http_response_pointer] mov rdi, VIRTIO_NET_TX_BUFFER + 64 rep movsb .checksums: @@ -1557,6 +1591,7 @@ ghal_anchor_tcp_payload_size: dw 0 ghal_anchor_rx_ipv4_header_size: dw 0 ghal_anchor_rx_tcp_offset: dw 0 ghal_anchor_rx_tcp_header_size: dw 0 +ghal_http_response_pointer: dq 0 %endif msg_ghal_net_discovered: db "GHOS_GHAL_VIRTIO_NET=DISCOVERED", 13, 10, 0 @@ -1575,6 +1610,15 @@ ghal_anchor_http_response: db "Content-Length: 286", 13, 10, 13, 10 db '{"schema":"guanghu.native-public-anchor/v1","anchor_id":"GLW-PUBLIC-NAV-ANCHOR-001","entry_path":"LL-CMPN-0001","world_node_id":"SYS-GLW-0001","repository_id":"REPO-012","branch":"main","code_entry":"https://guanghulab.com/code/bingshuo/guanghu-ice-heart","runtime":"GUANGHU_OS_NATIVE"}' ghal_anchor_http_response_end: +msg_ghal_code_channel_http_ready: db "GHOS_NATIVE_CODE_CHANNEL_HTTP=RESPONSE_TX", 13, 10, 0 +ghal_code_channel_http_response: + db "HTTP/1.1 200 OK", 13, 10 + db "Content-Type: application/json", 13, 10 + db "Cache-Control: no-store", 13, 10 + db "Connection: close", 13, 10 + db "Content-Length: 240", 13, 10, 13, 10 + db '{"schema":"guanghu.native-code-channel-read-only/v1","repository_id":"REPO-012","branch":"main","commit":"fb1096c5ecdcfb36015d51273f487c2f36d9c9cd","mode":"READ_ONLY_DISCOVERY","runtime":"GUANGHU_OS_NATIVE","full_forgejo_equivalence":false}' +ghal_code_channel_http_response_end: %endif msg_ghal_world_store_ready: db "GHOS_HLDP_WORLD_STORE=WRITE_READ_VERIFIED", 13, 10, 0 msg_ghal_code_channel_store_ready: db "GHOS_CODE_CHANNEL_STORE=WRITE_READ_VERIFIED", 13, 10, 0 diff --git a/product-source/hololake-platform/guanghu-os/scripts/qemu-native-net-peer.py b/product-source/hololake-platform/guanghu-os/scripts/qemu-native-net-peer.py index 0d415c7..a2fb37e 100644 --- a/product-source/hololake-platform/guanghu-os/scripts/qemu-native-net-peer.py +++ b/product-source/hololake-platform/guanghu-os/scripts/qemu-native-net-peer.py @@ -18,6 +18,8 @@ NATIVE_ACK_MAGIC = b"HLDP-NATIVE-ACK!" ANCHOR_PORT = 3922 ANCHOR_CLIENT_PORT = 40392 ANCHOR_CLIENT_SEQUENCE = 0x10203040 +CODE_CLIENT_PORT = 40393 +CODE_CLIENT_SEQUENCE = 0x20304050 ANCHOR_BODY = ( b'{"schema":"guanghu.native-public-anchor/v1",' b'"anchor_id":"GLW-PUBLIC-NAV-ANCHOR-001",' @@ -26,6 +28,13 @@ ANCHOR_BODY = ( b'"code_entry":"https://guanghulab.com/code/bingshuo/guanghu-ice-heart",' b'"runtime":"GUANGHU_OS_NATIVE"}' ) +CODE_BODY = ( + b'{"schema":"guanghu.native-code-channel-read-only/v1",' + b'"repository_id":"REPO-012","branch":"main",' + b'"commit":"fb1096c5ecdcfb36015d51273f487c2f36d9c9cd",' + b'"mode":"READ_ONLY_DISCOVERY","runtime":"GUANGHU_OS_NATIVE",' + b'"full_forgejo_equivalence":false}' +) def checksum(payload: bytes) -> int: @@ -105,13 +114,14 @@ def tcp_frame( acknowledgement: int, payload: bytes = b"", options: bytes = b"", + client_port: int = ANCHOR_CLIENT_PORT, ) -> bytes: if len(options) % 4 or len(options) > 40: raise ValueError("TCP options must be 32-bit aligned and no more than 40 bytes") tcp = bytearray( struct.pack( "!HHIIBBHHH", - ANCHOR_CLIENT_PORT, + client_port, ANCHOR_PORT, sequence, acknowledgement, @@ -137,7 +147,9 @@ def tcp_frame( return GUEST_MAC + PEER_MAC + b"\x08\x00" + bytes(ip) + bytes(tcp) -def verify_anchor_tcp(frame: bytes, expected_flags: int) -> tuple[int, int, bytes]: +def verify_anchor_tcp( + frame: bytes, expected_flags: int, client_port: int = ANCHOR_CLIENT_PORT +) -> tuple[int, int, bytes]: assert frame[0:6] == PEER_MAC assert frame[6:12] == GUEST_MAC assert frame[12:14] == b"\x08\x00" @@ -148,7 +160,7 @@ def verify_anchor_tcp(frame: bytes, expected_flags: int) -> tuple[int, int, byte total_length = int.from_bytes(frame[16:18], "big") tcp = frame[34 : 14 + total_length] assert int.from_bytes(tcp[0:2], "big") == ANCHOR_PORT - assert int.from_bytes(tcp[2:4], "big") == ANCHOR_CLIENT_PORT + assert int.from_bytes(tcp[2:4], "big") == client_port assert tcp[13] == expected_flags pseudo = GUEST_IP + GATEWAY_IP + b"\0\x06" + struct.pack("!H", len(tcp)) assert checksum(pseudo + tcp) == 0 @@ -170,6 +182,7 @@ def main() -> None: parser.add_argument("--recovery-token-file") parser.add_argument("--login-only", action="store_true") parser.add_argument("--anchor-http", action="store_true") + parser.add_argument("--service-equivalence", action="store_true") parser.add_argument("--guest-ip", default="172.16.0.6") parser.add_argument("--peer-ip", default="172.16.0.1") parser.add_argument("--relay-ip", default="43.153.193.169") @@ -192,7 +205,7 @@ def main() -> None: peer.bind(("127.0.0.1", args.listen_port)) peer.settimeout(0.2) qemu = ("127.0.0.1", args.qemu_port) - deadline = time.monotonic() + 15 + deadline = time.monotonic() + (30 if args.service_equivalence else 15) arp_verified = False login_count = 0 resident_login_count = 0 @@ -204,6 +217,11 @@ def main() -> None: anchor_server_sequence = None anchor_get_sent = False anchor_http_verified = False + code_syn_sent = False + code_syn_ack_verified = False + code_server_sequence = None + code_get_sent = False + code_http_verified = False while time.monotonic() < deadline: try: @@ -217,6 +235,46 @@ def main() -> None: if frame[12:14] != b"\x08\x00": continue if frame[23] == 6: + response_client_port = int.from_bytes(frame[36:38], "big") + if response_client_port == CODE_CLIENT_PORT: + if not code_syn_ack_verified: + server_sequence, acknowledgement, payload = verify_anchor_tcp( + frame, 0x12, CODE_CLIENT_PORT + ) + assert acknowledgement == CODE_CLIENT_SEQUENCE + 1 + assert payload == b"" + code_server_sequence = server_sequence + code_syn_ack_verified = True + request = ( + b"GET /v1/code-channel HTTP/1.1\r\n" + b"Host: native.guanghulab.com\r\n" + b"Connection: close\r\n\r\n" + ) + peer.sendto( + tcp_frame( + 0x18, + CODE_CLIENT_SEQUENCE + 1, + server_sequence + 1, + request, + options=b"\x01\x01\x08\x0a\xd8\x8d\xec\x57\x00\x00\x00\x01", + client_port=CODE_CLIENT_PORT, + ), + qemu, + ) + code_get_sent = True + continue + server_sequence, acknowledgement, payload = verify_anchor_tcp( + frame, 0x19, CODE_CLIENT_PORT + ) + assert code_server_sequence is not None + assert server_sequence == code_server_sequence + 1 + assert acknowledgement > CODE_CLIENT_SEQUENCE + 1 + header, body = payload.split(b"\r\n\r\n", 1) + assert b"HTTP/1.1 200 OK" in header + assert f"Content-Length: {len(CODE_BODY)}".encode() in header + assert body == CODE_BODY + code_http_verified = True + continue if not anchor_syn_ack_verified: server_sequence, acknowledgement, payload = verify_anchor_tcp(frame, 0x12) assert acknowledgement == ANCHOR_CLIENT_SEQUENCE + 1 @@ -249,6 +307,21 @@ def main() -> None: assert b"Content-Length: 286" in header assert body == ANCHOR_BODY anchor_http_verified = True + if args.service_equivalence and not code_syn_sent: + peer.sendto( + tcp_frame( + 0x02, + CODE_CLIENT_SEQUENCE, + 0, + options=( + b"\x02\x04\x05\x90\x04\x02\x08\x0a" + b"\xd8\x8d\xec\x57\x00\x00\x00\x00\x01\x03\x03\x07" + ), + client_port=CODE_CLIENT_PORT, + ), + qemu, + ) + code_syn_sent = True continue sequence = int.from_bytes(frame[40:42], "big") if sequence <= 3: @@ -273,12 +346,13 @@ def main() -> None: raise AssertionError(f"unexpected native sequence {sequence}") verified_request(frame, sequence, magic) peer.sendto(ordinary_reply(frame), qemu) - time.sleep(0.05) + time.sleep(0.005 if args.service_equivalence else 0.05) response_capability = NATIVE_ACK_MAGIC if ( args.final_resident and resident_login_count >= 3 and (not args.anchor_http or anchor_http_verified) + and (not args.service_equivalence or code_http_verified) ): response_capability = recovery_capability recovery_verified = True @@ -286,9 +360,9 @@ def main() -> None: for repetition in range(4): peer.sendto(reply, qemu) if repetition < 3: - time.sleep(0.01) + time.sleep(0.001 if args.service_equivalence else 0.01) if ( - args.anchor_http + (args.anchor_http or args.service_equivalence) and args.final_resident and sequence == 6 and not anchor_syn_sent @@ -336,12 +410,24 @@ def main() -> None: f"anchor_syn_sent: {str(anchor_syn_sent).lower()}\n" f"anchor_syn_ack_verified: {str(anchor_syn_ack_verified).lower()}\n" f"anchor_get_sent: {str(anchor_get_sent).lower()}\n" - f"anchor_http_verified: {str(anchor_http_verified).lower()}\n" + f"anchor_http_verified: {str(anchor_http_verified).lower()}\n" + f"code_syn_sent: {str(code_syn_sent).lower()}\n" + f"code_syn_ack_verified: {str(code_syn_ack_verified).lower()}\n" + f"code_get_sent: {str(code_get_sent).lower()}\n" + f"code_http_verified: {str(code_http_verified).lower()}\n" "recovery_selected_by_native: false\n" "login_magic: HLDP-GHOS-LOGIN!\n" ) return - raise SystemExit("timed out waiting for native outbound ICMP exchange") + raise SystemExit( + "timed out waiting for native service equivalence: " + f"anchor_syn_sent={anchor_syn_sent}, " + f"anchor_syn_ack_verified={anchor_syn_ack_verified}, " + f"anchor_http_verified={anchor_http_verified}, " + f"code_syn_sent={code_syn_sent}, " + f"code_syn_ack_verified={code_syn_ack_verified}, " + f"code_http_verified={code_http_verified}" + ) if __name__ == "__main__": diff --git a/product-source/hololake-platform/guanghu-os/scripts/test-native-final-resident-candidate.sh b/product-source/hololake-platform/guanghu-os/scripts/test-native-final-resident-candidate.sh index 241094a..e239208 100755 --- a/product-source/hololake-platform/guanghu-os/scripts/test-native-final-resident-candidate.sh +++ b/product-source/hololake-platform/guanghu-os/scripts/test-native-final-resident-candidate.sh @@ -50,11 +50,11 @@ python3 "${source_root}/scripts/qemu-native-net-peer.py" \ --qemu-port "${qemu_port}" \ --receipt "${test_root}/peer.hldp" \ --final-resident \ - --anchor-http \ + --service-equivalence \ --recovery-token-file "${token_file}" >"${test_root}/peer.log" 2>&1 & peer_pid=$! set +e -timeout 40 qemu-system-x86_64 \ +timeout "${GHOS_QEMU_TIMEOUT_SECONDS:-40}" qemu-system-x86_64 \ -machine pc,accel=tcg \ -m 64M \ -drive "if=none,id=ghboot,format=raw,file=${test_root}/disk.img" \ @@ -78,7 +78,10 @@ grep -q '^recovery_reply_verified: true$' "${test_root}/peer.hldp" grep -q '^recovery_selected_by_native: false$' "${test_root}/peer.hldp" grep -q '^anchor_syn_ack_verified: true$' "${test_root}/peer.hldp" grep -q '^anchor_http_verified: true$' "${test_root}/peer.hldp" +grep -q '^code_syn_ack_verified: true$' "${test_root}/peer.hldp" +grep -q '^code_http_verified: true$' "${test_root}/peer.hldp" grep -q '^GHOS_NATIVE_ANCHOR_HTTP=RESPONSE_TX' "${test_root}/serial.log" +grep -q '^GHOS_NATIVE_CODE_CHANNEL_HTTP=RESPONSE_TX' "${test_root}/serial.log" grep -q '^GHOS_NATIVE_RECOVERY_BEACON=WRITE_READ_VERIFIED' "${test_root}/serial.log" grep -q '^GHOS_DISK_PROOF_OBSERVED_AFTER_RESET=LBA134' "${test_root}/serial.log" @@ -172,6 +175,13 @@ native_anchor_service: world_node_id: SYS-GLW-0001 repository_id: REPO-012 runtime: GUANGHU_OS_NATIVE +native_code_channel_read_only: + http_get_v1_code_channel: PASS_100 + response_schema: guanghu.native-code-channel-read-only/v1 + repository_id: REPO-012 + branch: main + commit: fb1096c5ecdcfb36015d51273f487c2f36d9c9cd + full_forgejo_equivalence: false recovery_control: selected_by_native_runtime: false per_deployment_capability_required: true @@ -183,7 +193,8 @@ boundary: physical_server_capability: 0 native_anchor_http_qemu_capability: 100 native_anchor_http_physical_capability: 0 - code_channel_service_equivalence: 0 + native_code_channel_read_only_qemu_capability: 100 + public_code_channel_service_equivalence: 0 final_native_residency_proven: false -next_action: PHYSICAL_ONE_TIME_NATIVE_ANCHOR_HTTP_GATE_WITH_PROTECTED_RECOVERY +next_action: IMPLEMENT_AUTHENTICATED_NATIVE_TO_BS_GZ_006_TRANSPORT_AND_SEPARATE_PUBLIC_ANCHOR_FROM_FULL_CODE_CHANNEL_ACCEPTANCE EOF diff --git a/product-source/hololake-platform/guanghu-os/standards/jd-native-service-equivalence-contract.json b/product-source/hololake-platform/guanghu-os/standards/jd-native-service-equivalence-contract.json new file mode 100644 index 0000000..8afcac9 --- /dev/null +++ b/product-source/hololake-platform/guanghu-os/standards/jd-native-service-equivalence-contract.json @@ -0,0 +1,45 @@ +{ + "schema": "guanghu.jd-native-service-equivalence-contract/v1", + "node_id": "JD-FD-PRIMARY", + "candidate_source": "GUANGHU_OS_NATIVE", + "accepted_repository": { + "repository_id": "REPO-012", + "branch": "main", + "commit": "fb1096c5ecdcfb36015d51273f487c2f36d9c9cd" + }, + "native_read_only_surface": [ + { + "path": "/v1/anchor", + "schema": "guanghu.native-public-anchor/v1", + "required_anchor_id": "GLW-PUBLIC-NAV-ANCHOR-001" + }, + { + "path": "/v1/code-channel", + "schema": "guanghu.native-code-channel-read-only/v1", + "mode": "READ_ONLY_DISCOVERY", + "full_forgejo_equivalence": false + } + ], + "current_public_contract": { + "anchor_path": "/api/ai/v1/anchor", + "code_path": "/code/", + "front_door_node": "BS-GZ-006", + "transport_while_linux_hosted": "REVERSE_SSH_TUNNEL", + "survives_native_residency": false + }, + "acceptance_gates": { + "native_anchor_qemu": 100, + "native_code_channel_read_only_qemu": 100, + "native_physical_readback": 0, + "public_anchor_during_native_residency": 0, + "public_code_during_native_residency": 0, + "full_forgejo_equivalence": 0, + "production_native_cutover": 0 + }, + "prohibited_claims": [ + "A_READ_ONLY_SNAPSHOT_IS_FULL_FORGEJO", + "QEMU_IS_PHYSICAL_SERVER_READBACK", + "LINUX_HOSTED_TUNNEL_SURVIVES_NATIVE_BOOT", + "SOURCE_IMPLEMENTATION_IS_PRODUCTION_CUTOVER" + ] +} diff --git a/routing/guanghu-os-control-architecture.json b/routing/guanghu-os-control-architecture.json index 45cbfdd..8317564 100644 --- a/routing/guanghu-os-control-architecture.json +++ b/routing/guanghu-os-control-architecture.json @@ -1,7 +1,7 @@ { "schema": "guanghu.os-control-architecture/v1", "record_id": "HLP-GUANGHU-OS-CONTROL-001", - "version": "2026-08-15.3", + "version": "2026-08-15.4", "state": "CURRENT_CANONICAL", "final_topology": "GUANGHU_MASTER_WITH_ON_DEMAND_LINUX_SUBCONTROL_AND_RESCUE", "control_ownership": { @@ -39,7 +39,7 @@ "linux_on_demand_subcontrol": 0, "linux_rescue_preserved": 100, "final_guanghu_os_master": 0, - "next_engineering_gate": "IMPLEMENT_EQUIVALENT_SERVICE_CONTRACT_AND_INDEPENDENT_GUANGHU_SUPERVISOR_OWNERSHIP_BEFORE_ANY_BOOT_CUTOVER" + "next_engineering_gate": "IMPLEMENT_AUTHENTICATED_NATIVE_TO_BS_GZ_006_TRANSPORT_AND_PUBLIC_READBACK_BEFORE_ANY_BOOT_CUTOVER" }, "implementation": { "guanghu_supervisor_lifecycle_contract_source": 100, @@ -50,6 +50,12 @@ "linux_hosted_isolated_shadow_backend": 100, "real_isolated_linux_backend": 0, "jd_shadow_backend_physical_cycle": 100, + "native_service_equivalence_contract_source": 100, + "native_anchor_http_qemu_capability": 100, + "native_code_channel_read_only_qemu_capability": 100, + "public_native_anchor_equivalence": 0, + "public_native_code_channel_equivalence": 0, + "full_forgejo_equivalence": 0, "independent_guanghu_first_boot_supervisor": 0, "jd_physical_deployment": 0 }, @@ -66,6 +72,7 @@ "historical_linux_free_completion_formula_is_current": false, "adr_0172_linux_hosted_control_is_transition_not_final_topology": true }, + "native_service_equivalence_contract": "product-source/hololake-platform/guanghu-os/standards/jd-native-service-equivalence-contract.json", "architecture_page": "product-source/hololake-platform/architecture/HOLOLAKE-GUANGHU-OS-MASTER-AND-ON-DEMAND-LINUX-SUBCONTROL-20260810.md", "adr": "product-source/hololake-platform/docs/adr/0175-guanghu-os-master-and-on-demand-linux-subcontrol.md", "development_id": "DEV-20260810-012" diff --git a/routing/guanghu-os-control-architecture.test.mjs b/routing/guanghu-os-control-architecture.test.mjs index 5474998..1d8b4ca 100644 --- a/routing/guanghu-os-control-architecture.test.mjs +++ b/routing/guanghu-os-control-architecture.test.mjs @@ -9,6 +9,9 @@ const readJson = (relative) => JSON.parse(fs.readFileSync(path.join(root, relati const contract = readJson("routing/guanghu-os-control-architecture.json"); const architecture = readJson("routing/hololake-current-architecture.json"); const rules = readJson("routing/hololake-engineering-rules.json"); +const serviceContract = readJson( + "product-source/hololake-platform/guanghu-os/standards/jd-native-service-equivalence-contract.json", +); test("final topology makes Guanghu the master while preserving Linux as on-demand subcontrol and rescue", () => { assert.equal(contract.final_topology, "GUANGHU_MASTER_WITH_ON_DEMAND_LINUX_SUBCONTROL_AND_RESCUE"); @@ -32,7 +35,7 @@ test("current JD state stays transitional and cannot impersonate final master co }); test("the physical shadow cycle is registered without impersonating Guanghu-owned boot control", () => { - assert.equal(contract.version, "2026-08-15.3"); + assert.equal(contract.version, "2026-08-15.4"); assert.equal(contract.implementation.guanghu_supervisor_lifecycle_contract_source, 100); assert.equal(contract.implementation.target_readback_and_mandatory_reclaim_state_machine, 100); assert.equal(contract.implementation.declared_supervisor_core_line_and_function_coverage, 100); @@ -40,6 +43,12 @@ test("the physical shadow cycle is registered without impersonating Guanghu-owne assert.equal(contract.implementation.linux_hosted_isolated_shadow_backend, 100); assert.equal(contract.implementation.real_isolated_linux_backend, 0); assert.equal(contract.implementation.jd_shadow_backend_physical_cycle, 100); + assert.equal(contract.implementation.native_service_equivalence_contract_source, 100); + assert.equal(contract.implementation.native_anchor_http_qemu_capability, 100); + assert.equal(contract.implementation.native_code_channel_read_only_qemu_capability, 100); + assert.equal(contract.implementation.public_native_anchor_equivalence, 0); + assert.equal(contract.implementation.public_native_code_channel_equivalence, 0); + assert.equal(contract.implementation.full_forgejo_equivalence, 0); assert.equal(contract.implementation.independent_guanghu_first_boot_supervisor, 0); assert.equal(contract.implementation.jd_physical_deployment, 0); assert.equal(contract.current_target_evidence.final_state, "DORMANT"); @@ -54,3 +63,19 @@ test("current architecture and global engineering rules project the same control assert.equal(rules.server_os_control.linux_hosted_language_primary_is_final_master, false); assert.equal(rules.server_os_control.live_readback_predicates_required, true); }); + +test("native service surface is exact while every physical and public claim remains zero", () => { + assert.equal(serviceContract.node_id, "JD-FD-PRIMARY"); + assert.deepEqual( + serviceContract.native_read_only_surface.map((endpoint) => endpoint.path), + ["/v1/anchor", "/v1/code-channel"], + ); + assert.equal(serviceContract.accepted_repository.commit, "fb1096c5ecdcfb36015d51273f487c2f36d9c9cd"); + assert.equal(serviceContract.acceptance_gates.native_anchor_qemu, 100); + assert.equal(serviceContract.acceptance_gates.native_code_channel_read_only_qemu, 100); + assert.equal(serviceContract.acceptance_gates.native_physical_readback, 0); + assert.equal(serviceContract.acceptance_gates.public_anchor_during_native_residency, 0); + assert.equal(serviceContract.acceptance_gates.public_code_during_native_residency, 0); + assert.equal(serviceContract.acceptance_gates.full_forgejo_equivalence, 0); + assert.equal(serviceContract.acceptance_gates.production_native_cutover, 0); +});