From 8b5328993ebfec63f00f95dab510c19e817da761 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=86=B0=E6=9C=94?= <565183519@qq.com> Date: Fri, 7 Aug 2026 00:27:55 +0800 Subject: [PATCH 01/38] feat(native): add protected JD final residency control --- ...ATIVE-RESIDENCY-CONTROL-GATE-20260807.hdlp | 34 ++++ .../guanghu-os/native/x86_64-bios/boot.asm | 22 +++ .../native/x86_64-bios/ghal-virtio.asm | 19 +- .../build-native-final-resident-candidate.sh | 51 ++++++ .../install-jd-final-resident-relay.sh | 77 ++++++++ .../scripts/physical-native-icmp-peer.py | 111 +++++++++-- .../scripts/qemu-native-net-peer.py | 41 ++++- .../test-native-final-resident-candidate.sh | 172 ++++++++++++++++++ 8 files changed, 503 insertions(+), 24 deletions(-) create mode 100644 product-source/hololake-platform/guanghu-os/deployments/JD-FD-PRIMARY/FINAL-NATIVE-RESIDENCY-CONTROL-GATE-20260807.hdlp create mode 100755 product-source/hololake-platform/guanghu-os/scripts/build-native-final-resident-candidate.sh create mode 100755 product-source/hololake-platform/guanghu-os/scripts/install-jd-final-resident-relay.sh create mode 100755 product-source/hololake-platform/guanghu-os/scripts/test-native-final-resident-candidate.sh diff --git a/product-source/hololake-platform/guanghu-os/deployments/JD-FD-PRIMARY/FINAL-NATIVE-RESIDENCY-CONTROL-GATE-20260807.hdlp b/product-source/hololake-platform/guanghu-os/deployments/JD-FD-PRIMARY/FINAL-NATIVE-RESIDENCY-CONTROL-GATE-20260807.hdlp new file mode 100644 index 0000000..1b03437 --- /dev/null +++ b/product-source/hololake-platform/guanghu-os/deployments/JD-FD-PRIMARY/FINAL-NATIVE-RESIDENCY-CONTROL-GATE-20260807.hdlp @@ -0,0 +1,34 @@ +schema: guanghu.jd-final-native-residency-control-gate/v1 +gate_id: GH-OS-JD-FD-PRIMARY-001-FINAL-RESIDENCY-CONTROL +status: SOURCE_READY_QEMU_PASS_PHYSICAL_PENDING +node_id: JD-FD-PRIMARY +problem: + previous_native_default: PASS_100 + previous_native_runtime_selected_recovery_itself: true + final_native_residency_proven: false +required_model: + normal_state: GUANGHU_OS_NATIVE_RESIDENT + native_runtime_autonomously_selects_recovery: false + outbound_relay_keeps_nat_path_alive: true + ordinary_reply: HLDP-NATIVE-ACK + recovery_reply: PER_DEPLOYMENT_128_BIT_CAPABILITY + recovery_request_authority: EXPLICIT_ROOT_ACTION_ON_BS-SG-003 + token_repository_exposure: forbidden + wrong_capability: IGNORE_AND_REMAIN_NATIVE +qemu_acceptance: + native_initial_pipeline: PASS_100 + native_remained_resident_before_authorized_recovery: PASS_100 + wrong_capability_ignored: PASS_100 + protected_recovery_capability_returned_to_linux: PASS_100 +physical_acceptance: + source_published: pending + relay_installed: pending + one_time_final_candidate_booted: pending + sustained_native_residency_observed: pending + explicit_recovery_request_verified: pending + returned_linux_and_beacon_cleared: pending + final_native_residency_proven: false +boundary: + qemu_capability: 100 + physical_server_capability: 0 + do_not_claim_final_residency_until_physical_gate: true diff --git a/product-source/hololake-platform/guanghu-os/native/x86_64-bios/boot.asm b/product-source/hololake-platform/guanghu-os/native/x86_64-bios/boot.asm index 536eaa7..d21f02a 100644 --- a/product-source/hololake-platform/guanghu-os/native/x86_64-bios/boot.asm +++ b/product-source/hololake-platform/guanghu-os/native/x86_64-bios/boot.asm @@ -216,6 +216,27 @@ long_mode_start: jc native_block_proof_error call ghal_block_persist_branch_receipt jc native_world_store_error +%ifdef GHOS_NATIVE_FINAL_RESIDENT + mov byte [rel physical_proof_flag], 0xa7 + call ghal_block_write_proof + jc native_block_proof_error +.final_resident_loop: + ; Keep the outbound NAT path alive. Recovery is selected by the protected + ; relay capability, never autonomously by the native runtime. + mov byte [rel ghal_net_expected_sequence], 6 + lea rax, [rel ghal_login_magic] + mov [rel ghal_net_expected_magic], rax + mov byte [rel ghal_net_command_kind], 0 + call ghal_net_icmp_exchange_once + jc .final_resident_loop + cmp byte [rel ghal_net_matched_kind], 3 + jne .final_resident_loop + call ghal_write_native_recovery_beacon + jc native_world_store_error + call ghal_block_write_proof + jc native_block_proof_error + jmp hardware_reset64 +%else %ifdef GHOS_NATIVE_RESIDENT mov ecx, 10 .resident_login_loop: @@ -240,6 +261,7 @@ long_mode_start: jc native_block_proof_error call ghal_write_native_recovery_beacon jc native_world_store_error +%endif %endif mov byte [rel physical_proof_flag], 0xa7 %endif 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 990143f..8ea7310 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 @@ -1148,14 +1148,26 @@ ghal_net_icmp_exchange_once: lea rdi, [rel ghal_native_ack_magic] mov ecx, GHOS_LOGIN_MAGIC_SIZE repe cmpsb + je .expected_magic_match +%ifdef GHOS_NATIVE_FINAL_RESIDENT + cmp byte [rel ghal_net_command_kind], 0 jne .ignore_packet - jmp .expected_magic_match + mov rsi, VIRTIO_NET_RX_BUFFER + GHOS_LOGIN_MAGIC_OFFSET + GHOS_LOGIN_MAGIC_SIZE + lea rdi, [rel ghal_recovery_capability] + mov ecx, GHOS_LOGIN_MAGIC_SIZE + repe cmpsb + jne .ignore_packet + mov byte [rel ghal_net_matched_kind], 3 + jmp .matched_kind_ready +%else + jmp .ignore_packet +%endif .expected_magic_match: mov al, [rel ghal_net_command_kind] -.store_matched_kind: mov [rel ghal_net_matched_kind], al +.matched_kind_ready: cmp byte [rel ghal_net_matched_kind], 0 jne .record_command mov byte [rel physical_proof_ipv4_rx_verified], 1 @@ -1299,6 +1311,9 @@ ghal_code_commit_magic: db "HLDP-CODE-COMMIT" ghal_branch_move_magic: db "HLDP-BRANCH-MOVE" ghal_recovery_magic: db "HLDP-RECOVER-OS!" ghal_native_ack_magic: db "HLDP-NATIVE-ACK!" +%ifdef GHOS_NATIVE_FINAL_RESIDENT +%include "recovery-token.inc" +%endif ghal_branch_receipt_template: db "GHOS_BRANCH_MAIN_V1", 10 db "channel=HLP-MOD-CODE-CHANNEL", 10 diff --git a/product-source/hololake-platform/guanghu-os/scripts/build-native-final-resident-candidate.sh b/product-source/hololake-platform/guanghu-os/scripts/build-native-final-resident-candidate.sh new file mode 100755 index 0000000..a998837 --- /dev/null +++ b/product-source/hololake-platform/guanghu-os/scripts/build-native-final-resident-candidate.sh @@ -0,0 +1,51 @@ +#!/usr/bin/env bash +set -euo pipefail + +[[ $# -eq 3 ]] || { + echo "usage: build-native-final-resident-candidate.sh " >&2 + exit 64 +} + +world_root=$(readlink -f "$1") +output_root=$(readlink -m "$2") +token_file=$(readlink -f "$3") +source_root=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd) +native_root=${source_root}/native/x86_64-bios + +command -v nasm >/dev/null +token_hex=$(tr -d '\r\n ' <"${token_file}") +[[ ${token_hex} =~ ^[0-9a-fA-F]{32}$ ]] || { + echo "recovery token must be exactly 16 bytes encoded as 32 hexadecimal characters" >&2 + exit 65 +} + +mkdir -p "${output_root}" +chmod 0700 "${output_root}" +cargo run --quiet --manifest-path "${source_root}/Cargo.toml" \ + -p hldp-native-compiler -- "${world_root}" "${output_root}/world.inc" +{ + printf 'ghal_recovery_capability: db ' + for index in $(seq 0 15); do + [[ ${index} -eq 0 ]] || printf ',' + printf '0x%s' "${token_hex:$((index * 2)):2}" + done + printf '\n' +} >"${output_root}/recovery-token.inc" +chmod 0600 "${output_root}/recovery-token.inc" + +layout_args=() +while IFS= read -r argument; do layout_args+=("${argument}"); done \ + < <("${source_root}/scripts/native-layout-nasm-args.sh" "${world_root}") +( + cd "${output_root}" + nasm -f bin -I "${output_root}/" -I "${native_root}/" \ + "${layout_args[@]}" \ + -dGHOS_PHYSICAL_CANDIDATE=1 \ + -dGHOS_NATIVE_RESIDENT=1 \ + -dGHOS_NATIVE_FINAL_RESIDENT=1 \ + "${native_root}/boot.asm" \ + -o guanghu-os-x86_64-bios-final-resident.img +) +[[ $(stat -c %s "${output_root}/guanghu-os-x86_64-bios-final-resident.img") -eq 14848 ]] +sha256sum "${output_root}/guanghu-os-x86_64-bios-final-resident.img" \ + >"${output_root}/guanghu-os-x86_64-bios-final-resident.img.sha256" diff --git a/product-source/hololake-platform/guanghu-os/scripts/install-jd-final-resident-relay.sh b/product-source/hololake-platform/guanghu-os/scripts/install-jd-final-resident-relay.sh new file mode 100755 index 0000000..946d909 --- /dev/null +++ b/product-source/hololake-platform/guanghu-os/scripts/install-jd-final-resident-relay.sh @@ -0,0 +1,77 @@ +#!/usr/bin/env bash +set -euo pipefail + +[[ $# -eq 5 ]] || { + echo "usage: install-jd-final-resident-relay.sh " >&2 + exit 64 +} +[[ ${EUID} -eq 0 ]] || exit 77 + +peer_script=$(readlink -f "$1") +token_file=$(readlink -f "$2") +allowed_source=$3 +request_file=$(readlink -m "$4") +receipt_file=$(readlink -m "$5") + +token_hex=$(tr -d '\r\n ' <"${token_file}") +[[ ${token_hex} =~ ^[0-9a-fA-F]{32}$ ]] || exit 65 +[[ ${allowed_source} =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]] || exit 65 +[[ ${request_file} == /run/guanghu-jd-native-final-recovery.request ]] || exit 65 +[[ ${receipt_file} == /var/lib/guanghu-os/jd-final-resident-relay.hldp ]] || exit 65 + +install -D -m 0755 "${peer_script}" \ + /usr/local/libexec/guanghu-os/physical-native-icmp-peer.py +install -D -m 0600 "${token_file}" \ + /etc/guanghu-os/jd-final-resident-recovery-token.hex +install -d -m 0700 /var/lib/guanghu-os +rm -f "${request_file}" + +install -m 0644 /dev/stdin \ + /etc/systemd/system/guanghu-jd-native-final-resident-relay.service </dev/null +echo "installed but not started" diff --git a/product-source/hololake-platform/guanghu-os/scripts/physical-native-icmp-peer.py b/product-source/hololake-platform/guanghu-os/scripts/physical-native-icmp-peer.py index 1854fbf..0df0b2b 100755 --- a/product-source/hololake-platform/guanghu-os/scripts/physical-native-icmp-peer.py +++ b/product-source/hololake-platform/guanghu-os/scripts/physical-native-icmp-peer.py @@ -1,5 +1,6 @@ #!/usr/bin/env python3 import argparse +import os import pathlib import socket import struct @@ -72,12 +73,17 @@ def verify_native_request(packet: bytes, pipeline: list[bytes]) -> tuple[int, st return sequence, source -def native_ack_reply(packet: bytes) -> bytes: +def native_ack_reply( + packet: bytes, + response_capability: bytes = NATIVE_ACK_MAGIC, +) -> bytes: + if len(response_capability) != 16: + raise ValueError("response capability must be exactly 16 bytes") header_length = (packet[0] & 0x0F) * 4 icmp = bytearray(packet[header_length:]) icmp[0] = 0 icmp[2:4] = b"\0\0" - icmp[32:48] = NATIVE_ACK_MAGIC + icmp[32:48] = response_capability icmp[2:4] = struct.pack("!H", checksum(bytes(icmp))) return bytes(icmp) @@ -122,6 +128,9 @@ def main() -> None: parser.add_argument("--resume-resident-count", type=int) parser.add_argument("--resident-pipeline", action="store_true") parser.add_argument("--native-relay", action="store_true") + parser.add_argument("--final-resident-relay", action="store_true") + parser.add_argument("--recovery-token-file") + parser.add_argument("--recovery-request-file") parser.add_argument("--allowed-source") parser.add_argument("--native-ack-delay", type=float, default=0.25) parser.add_argument("--native-ack-repetitions", type=int, default=4) @@ -149,37 +158,66 @@ def main() -> None: args.resume_resident_count is not None, args.resident_pipeline, args.native_relay, + args.final_resident_relay, ) ) > 1: raise SystemExit( "--resident, --login-only, --resume-after-login, and " "--resume-after-commit, --resume-after-branch, and " - "--resume-resident-count, --resident-pipeline, and --native-relay " + "--resume-resident-count, --resident-pipeline, --native-relay, " + "and --final-resident-relay " "are mutually exclusive" ) socket_type = socket.SOCK_RAW if args.raw_socket else socket.SOCK_DGRAM peer = socket.socket(socket.AF_INET, socket_type, socket.IPPROTO_ICMP) deadline = time.monotonic() + args.timeout - if args.native_relay: + if args.native_relay or args.final_resident_relay: if not args.raw_socket: - raise SystemExit("--native-relay requires --raw-socket") + raise SystemExit("native relay modes require --raw-socket") if not args.allowed_source: - raise SystemExit("--native-relay requires --allowed-source") + raise SystemExit("native relay modes require --allowed-source") + recovery_capability = None + if args.final_resident_relay: + if not args.recovery_token_file or not args.recovery_request_file: + raise SystemExit( + "--final-resident-relay requires --recovery-token-file " + "and --recovery-request-file" + ) + token_hex = ( + pathlib.Path(args.recovery_token_file) + .read_text(encoding="ascii") + .strip() + ) + recovery_capability = bytes.fromhex(token_hex) + if len(recovery_capability) != 16: + raise SystemExit("recovery token must be exactly 16 bytes") allowed_source = socket.gethostbyname(args.allowed_source) - pipeline = [ - LOGIN_MAGIC, - LOGIN_MAGIC, - LOGIN_MAGIC, - COMMIT_MAGIC, - BRANCH_MAGIC, - *([LOGIN_MAGIC] * 10), - RECOVERY_MAGIC, - ] + pipeline = ( + [ + LOGIN_MAGIC, + LOGIN_MAGIC, + LOGIN_MAGIC, + COMMIT_MAGIC, + BRANCH_MAGIC, + LOGIN_MAGIC, + ] + if args.final_resident_relay + else [ + LOGIN_MAGIC, + LOGIN_MAGIC, + LOGIN_MAGIC, + COMMIT_MAGIC, + BRANCH_MAGIC, + *([LOGIN_MAGIC] * 10), + RECOVERY_MAGIC, + ] + ) peer.settimeout(0.5) acknowledged: set[int] = set() sources: set[str] = set() completed_at: float | None = None + recovery_capability_sent = False while time.monotonic() < deadline and ( completed_at is None or time.monotonic() < completed_at + 5.0 ): @@ -196,7 +234,15 @@ def main() -> None: # Repeat the authenticated frame because the physical JD path can # lose a single raw-socket reply after NAT has been established. time.sleep(args.native_ack_delay) - reply = native_ack_reply(packet) + response_capability = NATIVE_ACK_MAGIC + if ( + args.final_resident_relay + and sequence == 6 + and os.path.isfile(args.recovery_request_file) + ): + response_capability = recovery_capability + recovery_capability_sent = True + reply = native_ack_reply(packet, response_capability) for repetition in range(args.native_ack_repetitions): peer.sendto(reply, address) if repetition + 1 < args.native_ack_repetitions: @@ -208,8 +254,39 @@ def main() -> None: ) acknowledged.add(sequence) sources.add(source) - if len(acknowledged) == len(pipeline) and completed_at is None: + if args.final_resident_relay: + ready = all(sequence_id in acknowledged for sequence_id in range(1, 7)) + receipt = pathlib.Path(args.receipt) + receipt.write_text( + "schema: guanghu.physical-native-final-resident-relay/v1\n" + f"status: {'RECOVERY_CAPABILITY_SENT' if recovery_capability_sent else 'READY_NATIVE_RESIDENT' if ready else 'STARTING'}\n" + "handshake_direction: NATIVE_INITIATED_OUTBOUND_ICMP\n" + "native_ack_marker: HLDP-NATIVE-ACK!\n" + "relay_cannot_select_command: true\n" + "recovery_requires_root_owned_request_file: true\n" + f"recovery_capability_sent: {str(recovery_capability_sent).lower()}\n" + f"acknowledged_sequences: {','.join(str(item) for item in sorted(acknowledged))}\n" + f"observed_nat_sources: {','.join(sorted(sources))}\n", + encoding="utf-8", + ) + if ready and recovery_capability_sent and completed_at is None: + completed_at = time.monotonic() + elif len(acknowledged) == len(pipeline) and completed_at is None: completed_at = time.monotonic() + if args.final_resident_relay: + if not all(sequence_id in acknowledged for sequence_id in range(1, 7)): + raise TimeoutError( + "native final-resident relay did not reach ready state; " + "acknowledged sequences: " + + ",".join(str(item) for item in sorted(acknowledged)) + ) + if not recovery_capability_sent: + raise TimeoutError( + "native final-resident relay remained ready but no " + "authorized recovery request was observed" + ) + print(pathlib.Path(args.receipt).read_text(encoding="utf-8"), end="") + return if len(acknowledged) != len(pipeline): raise TimeoutError( "native relay pipeline incomplete; acknowledged sequences: " 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 368acf7..04aa690 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 @@ -78,10 +78,12 @@ def ordinary_reply(frame: bytes) -> bytes: return bytes(reply) -def authenticated_reply(frame: bytes, magic: bytes) -> bytes: +def authenticated_reply(frame: bytes, response_capability: bytes = NATIVE_ACK_MAGIC) -> bytes: + if len(response_capability) != 16: + raise ValueError("response capability must be exactly 16 bytes") reply = bytearray(ordinary_reply(frame)) reply[36:38] = b"\0\0" - reply[66:82] = NATIVE_ACK_MAGIC + reply[66:82] = response_capability reply[36:38] = struct.pack("!H", checksum(bytes(reply[34:82]))) return bytes(reply) @@ -93,11 +95,23 @@ def main() -> None: parser.add_argument("--qemu-port", type=int, required=True) parser.add_argument("--receipt", required=True) parser.add_argument("--resident", action="store_true") + parser.add_argument("--final-resident", action="store_true") + parser.add_argument("--recovery-token-file") parser.add_argument("--login-only", 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") args = parser.parse_args() + if sum((args.resident, args.final_resident, args.login_only)) > 1: + raise SystemExit("--resident, --final-resident and --login-only are mutually exclusive") + if args.final_resident and not args.recovery_token_file: + raise SystemExit("--final-resident requires --recovery-token-file") + recovery_capability = None + if args.recovery_token_file: + token_hex = open(args.recovery_token_file, encoding="ascii").read().strip() + recovery_capability = bytes.fromhex(token_hex) + if len(recovery_capability) != 16: + raise SystemExit("recovery token must be exactly 16 bytes") GUEST_IP = socket.inet_aton(args.guest_ip) GATEWAY_IP = socket.inet_aton(args.peer_ip) RELAY_IP = socket.inet_aton(args.relay_ip) @@ -135,6 +149,9 @@ def main() -> None: elif sequence == 5: magic = BRANCH_MAGIC branch_verified = True + elif args.final_resident and sequence == 6: + magic = LOGIN_MAGIC + resident_login_count += 1 elif 6 <= sequence <= 15: magic = LOGIN_MAGIC resident_login_count += 1 @@ -146,14 +163,26 @@ def main() -> None: verified_request(frame, sequence, magic) peer.sendto(ordinary_reply(frame), qemu) time.sleep(0.05) - reply = authenticated_reply(frame, magic) + response_capability = NATIVE_ACK_MAGIC + if args.final_resident and resident_login_count >= 3: + response_capability = recovery_capability + recovery_verified = True + reply = authenticated_reply(frame, response_capability) for repetition in range(4): peer.sendto(reply, qemu) if repetition < 3: time.sleep(0.01) - terminal_sequence = 3 if args.login_only else (16 if args.resident else 5) - if sequence != terminal_sequence: + terminal = ( + sequence == 3 + if args.login_only + else recovery_verified + if args.final_resident + else sequence == 16 + if args.resident + else sequence == 5 + ) + if not terminal: continue with open(args.receipt, "w", encoding="utf-8") as output: output.write( @@ -169,6 +198,8 @@ def main() -> None: f"branch_move_reply_verified: {str(branch_verified).lower()}\n" f"resident_login_reply_count: {resident_login_count}\n" f"recovery_reply_verified: {str(recovery_verified).lower()}\n" + f"final_resident_control: {str(args.final_resident).lower()}\n" + "recovery_selected_by_native: false\n" "login_magic: HLDP-GHOS-LOGIN!\n" ) return 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 new file mode 100755 index 0000000..50429cd --- /dev/null +++ b/product-source/hololake-platform/guanghu-os/scripts/test-native-final-resident-candidate.sh @@ -0,0 +1,172 @@ +#!/usr/bin/env bash +set -euo pipefail + +[[ $# -eq 3 ]] || { + echo "usage: test-native-final-resident-candidate.sh " >&2 + exit 64 +} + +candidate=$(readlink -f "$1") +token_file=$(readlink -f "$2") +receipt=$(readlink -m "$3") +source_root=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd) +native_root=${source_root}/native/x86_64-bios +test_root=$(mktemp -d) +peer_pid= +cleanup() { + if [[ -n ${peer_pid} ]]; then + kill "${peer_pid}" 2>/dev/null || true + fi + if [[ ${GHOS_KEEP_TEST_ROOT:-0} != 1 ]]; then + rm -rf "${test_root}" + else + echo "GHOS_TEST_ROOT=${test_root}" >&2 + fi +} +trap cleanup EXIT + +[[ $(stat -c %s "${candidate}") -eq 14848 ]] +[[ $(tr -d '\r\n ' <"${token_file}" | wc -c) -eq 32 ]] +python3 - "${token_file}" "${test_root}/wrong-token.hex" <<'PY' +import pathlib +import sys + +token = bytearray.fromhex(pathlib.Path(sys.argv[1]).read_text().strip()) +token[0] ^= 0x01 +pathlib.Path(sys.argv[2]).write_text(token.hex() + "\n", encoding="ascii") +PY +truncate -s 700M "${test_root}/disk.img" +nasm -f bin -dCANDIDATE_LBA=105 -dPROOF_LBA=134 \ + "${native_root}/physical-test-mbr.asm" -o "${test_root}/mbr.bin" +dd if="${test_root}/mbr.bin" of="${test_root}/disk.img" \ + bs=512 seek=0 conv=notrunc status=none +dd if="${candidate}" of="${test_root}/disk.img" \ + bs=512 seek=105 conv=notrunc status=none + +peer_port=$((33000 + ${BASHPID:-$$} % 1000)) +qemu_port=$((peer_port + 1)) +python3 "${source_root}/scripts/qemu-native-net-peer.py" \ + --listen-port "${peer_port}" \ + --qemu-port "${qemu_port}" \ + --receipt "${test_root}/peer.hldp" \ + --final-resident \ + --recovery-token-file "${token_file}" >"${test_root}/peer.log" 2>&1 & +peer_pid=$! +set +e +timeout 40 qemu-system-x86_64 \ + -machine pc,accel=tcg \ + -m 64M \ + -drive "if=none,id=ghboot,format=raw,file=${test_root}/disk.img" \ + -device virtio-blk-pci,drive=ghboot,disable-modern=on,bootindex=0 \ + -netdev "dgram,id=ghnet,local.type=inet,local.host=127.0.0.1,local.port=${qemu_port},remote.type=inet,remote.host=127.0.0.1,remote.port=${peer_port}" \ + -device virtio-net-pci,netdev=ghnet,disable-modern=on,mac=52:54:00:26:71:98 \ + -display none \ + -monitor none \ + -serial "file:${test_root}/serial.log" \ + -device isa-debug-exit,iobase=0xf4,iosize=0x04 +qemu_status=$? +set -e +[[ ${qemu_status} -eq 33 ]] +wait "${peer_pid}" +peer_pid= + +grep -q '^final_resident_control: true$' "${test_root}/peer.hldp" +grep -q '^resident_login_reply_count: 3$' "${test_root}/peer.hldp" +grep -q '^recovery_reply_verified: true$' "${test_root}/peer.hldp" +grep -q '^recovery_selected_by_native: false$' "${test_root}/peer.hldp" +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" + +python3 - "${test_root}/disk.img" <<'PY' +import pathlib +import sys + +with pathlib.Path(sys.argv[1]).open("rb") as disk: + def sector(lba: int, count: int = 1) -> bytes: + disk.seek(lba * 512) + return disk.read(count * 512) + + proof = sector(134) + assert proof[0] == 0xA7 + assert proof[1:].startswith(b"GHOS_NATIVE_LONG64_DISK_PROOF\0") + assert proof[99:102] == bytes([1, 1, 1]) + assert proof[102:105] == bytes([1, 1, 1]) + assert proof[105] == 6 + assert sector(139, 2).startswith(b"# GRUB Environment Block\n") + assert sector(141).startswith(b"GHOS_GHCIP_INDEX_V1\n") +PY + +truncate -s 700M "${test_root}/wrong-capability-disk.img" +dd if="${test_root}/mbr.bin" of="${test_root}/wrong-capability-disk.img" \ + bs=512 seek=0 conv=notrunc status=none +dd if="${candidate}" of="${test_root}/wrong-capability-disk.img" \ + bs=512 seek=105 conv=notrunc status=none +wrong_peer_port=$((peer_port + 2)) +wrong_qemu_port=$((qemu_port + 2)) +python3 "${source_root}/scripts/qemu-native-net-peer.py" \ + --listen-port "${wrong_peer_port}" \ + --qemu-port "${wrong_qemu_port}" \ + --receipt "${test_root}/wrong-peer.hldp" \ + --final-resident \ + --recovery-token-file "${test_root}/wrong-token.hex" \ + >"${test_root}/wrong-peer.log" 2>&1 & +peer_pid=$! +set +e +timeout 5 qemu-system-x86_64 \ + -machine pc,accel=tcg \ + -m 64M \ + -drive "if=none,id=ghboot,format=raw,file=${test_root}/wrong-capability-disk.img" \ + -device virtio-blk-pci,drive=ghboot,disable-modern=on,bootindex=0 \ + -netdev "dgram,id=ghnet,local.type=inet,local.host=127.0.0.1,local.port=${wrong_qemu_port},remote.type=inet,remote.host=127.0.0.1,remote.port=${wrong_peer_port}" \ + -device virtio-net-pci,netdev=ghnet,disable-modern=on,mac=52:54:00:26:71:98 \ + -display none \ + -monitor none \ + -serial "file:${test_root}/wrong-capability-serial.log" \ + -device isa-debug-exit,iobase=0xf4,iosize=0x04 +wrong_qemu_status=$? +set -e +[[ ${wrong_qemu_status} -eq 124 ]] +wait "${peer_pid}" +peer_pid= +python3 - "${test_root}/wrong-capability-disk.img" <<'PY' +import pathlib +import sys + +with pathlib.Path(sys.argv[1]).open("rb") as disk: + disk.seek(134 * 512) + proof = disk.read(512) + disk.seek(139 * 512) + recovery = disk.read(1024) +assert proof[0] == 0xA7 +assert recovery == bytes(1024) +PY + +observed_at=$(date --iso-8601=seconds) +image_sha=$(sha256sum "${candidate}" | awk '{print $1}') +cat >"${receipt}" < Date: Fri, 7 Aug 2026 00:33:19 +0800 Subject: [PATCH 02/38] fix(native): gate JD final candidate replacement --- ...lace-jd-native-final-resident-candidate.sh | 97 +++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100755 product-source/hololake-platform/guanghu-os/scripts/replace-jd-native-final-resident-candidate.sh diff --git a/product-source/hololake-platform/guanghu-os/scripts/replace-jd-native-final-resident-candidate.sh b/product-source/hololake-platform/guanghu-os/scripts/replace-jd-native-final-resident-candidate.sh new file mode 100755 index 0000000..eb82a8a --- /dev/null +++ b/product-source/hololake-platform/guanghu-os/scripts/replace-jd-native-final-resident-candidate.sh @@ -0,0 +1,97 @@ +#!/usr/bin/env bash +set -euo pipefail + +[[ $# -eq 6 ]] || { + echo "usage: replace-jd-native-final-resident-candidate.sh " >&2 + exit 64 +} +[[ ${EUID} -eq 0 ]] || exit 77 + +world_root=$(readlink -f "$1") +candidate=$(readlink -f "$2") +recovery_root=$(readlink -m "$3") +expected_old_sha=$4 +expected_new_sha=$5 +accepted_source_commit=$6 + +grep -q '^node_id: JD-FD-PRIMARY$' "${world_root}/CURRENT.hldp" +/guanghu/bin/ghctl authorize "${world_root}" \ + write_bootloader_and_system_partitions >/dev/null +[[ ${expected_old_sha} =~ ^[0-9a-f]{64}$ ]] +[[ ${expected_new_sha} =~ ^[0-9a-f]{64}$ ]] +[[ ${accepted_source_commit} =~ ^[0-9a-f]{40}$ ]] +[[ $(stat -c %s "${candidate}") -eq 14848 ]] +[[ $(sha256sum "${candidate}" | awk '{print $1}') == "${expected_new_sha}" ]] +[[ ! -e ${recovery_root} ]] + +partition_dump=$(sfdisk -d /dev/vda) +grep -q '^label: dos$' <<<"${partition_dump}" +grep -q '^label-id: 0xf4bb72a5$' <<<"${partition_dump}" +grep -Eq '^/dev/vda1 : start= *2048, size= *209713119, type=83$' \ + <<<"${partition_dump}" +observed_old_sha=$(dd if=/dev/vda bs=512 skip=105 count=29 status=none | + sha256sum | awk '{print $1}') +[[ ${observed_old_sha} == "${expected_old_sha}" ]] + +dd if=/dev/vda bs=512 skip=135 count=1 status=none | + grep -aq '^GHOS_HLDP_WORLD_STORE_V1' +dd if=/dev/vda bs=512 skip=136 count=1 status=none | + grep -aq '^GHOS_CODE_CHANNEL_STORE_V1' +dd if=/dev/vda bs=512 skip=138 count=1 status=none | + grep -aq '^GHOS_BRANCH_MAIN_V1' +dd if=/dev/vda bs=512 skip=141 count=1 status=none | + grep -aq '^GHOS_GHCIP_INDEX_V1' +dd if=/dev/vda bs=512 skip=142 count=1 status=none | + grep -aq '^GHOS_GHCIP_ROOT_V1' +grep -q '^GRUB_DEFAULT=guanghu-jd-native-once$' /etc/default/grub +grep -q 'set default="guanghu-jd-native-once"' /boot/grub/grub.cfg + +mkdir -m 0700 "${recovery_root}" +printf '%s\n' "${partition_dump}" >"${recovery_root}/sfdisk-before.txt" +disk_sectors=$(blockdev --getsz /dev/vda) +dd if=/dev/vda of="${recovery_root}/first-2MiB.before.bin" \ + bs=1M count=2 status=none +dd if=/dev/vda of="${recovery_root}/last-2MiB.before.bin" \ + bs=512 skip=$((disk_sectors - 4096)) count=4096 status=none +dd if=/dev/vda of="${recovery_root}/previous-native-candidate.img" \ + bs=512 skip=105 count=29 status=none +cp /boot/grub/grub.cfg "${recovery_root}/grub.cfg.before" +cp /boot/grub/grubenv "${recovery_root}/grubenv.before" +cp /etc/default/grub "${recovery_root}/default-grub.before" +cp "${candidate}" "${recovery_root}/jd-native-final-resident.img" + +dd if="${candidate}" of=/dev/vda bs=512 seek=105 count=29 \ + conv=notrunc,fsync status=none +observed_new_sha=$(dd if=/dev/vda bs=512 skip=105 count=29 status=none | + sha256sum | awk '{print $1}') +[[ ${observed_new_sha} == "${expected_new_sha}" ]] + +observed_at=$(date --iso-8601=seconds) +cat >"${recovery_root}/REPLACE-RECEIPT.hldp" < Date: Fri, 7 Aug 2026 00:42:21 +0800 Subject: [PATCH 03/38] docs(native): record JD final physical residency --- ...ATIVE-RESIDENCY-CONTROL-GATE-20260807.hdlp | 28 +++++--- ...E-RESIDENCY-PHYSICAL-RECEIPT-20260807.hdlp | 69 +++++++++++++++++++ 2 files changed, 87 insertions(+), 10 deletions(-) create mode 100644 product-source/hololake-platform/guanghu-os/deployments/JD-FD-PRIMARY/FINAL-NATIVE-RESIDENCY-PHYSICAL-RECEIPT-20260807.hdlp diff --git a/product-source/hololake-platform/guanghu-os/deployments/JD-FD-PRIMARY/FINAL-NATIVE-RESIDENCY-CONTROL-GATE-20260807.hdlp b/product-source/hololake-platform/guanghu-os/deployments/JD-FD-PRIMARY/FINAL-NATIVE-RESIDENCY-CONTROL-GATE-20260807.hdlp index 1b03437..02a8ffd 100644 --- a/product-source/hololake-platform/guanghu-os/deployments/JD-FD-PRIMARY/FINAL-NATIVE-RESIDENCY-CONTROL-GATE-20260807.hdlp +++ b/product-source/hololake-platform/guanghu-os/deployments/JD-FD-PRIMARY/FINAL-NATIVE-RESIDENCY-CONTROL-GATE-20260807.hdlp @@ -1,6 +1,6 @@ schema: guanghu.jd-final-native-residency-control-gate/v1 gate_id: GH-OS-JD-FD-PRIMARY-001-FINAL-RESIDENCY-CONTROL -status: SOURCE_READY_QEMU_PASS_PHYSICAL_PENDING +status: PHYSICAL_CONTROL_PASS_PRODUCTION_CUTOVER_BLOCKED node_id: JD-FD-PRIMARY problem: previous_native_default: PASS_100 @@ -21,14 +21,22 @@ qemu_acceptance: wrong_capability_ignored: PASS_100 protected_recovery_capability_returned_to_linux: PASS_100 physical_acceptance: - source_published: pending - relay_installed: pending - one_time_final_candidate_booted: pending - sustained_native_residency_observed: pending - explicit_recovery_request_verified: pending - returned_linux_and_beacon_cleared: pending - final_native_residency_proven: false + source_published: PASS_100 + relay_installed: PASS_100 + one_time_final_candidate_booted: PASS_100 + sustained_native_residency_observed: PASS_100 + explicit_recovery_request_verified: PASS_100 + returned_linux_and_beacon_cleared: PASS_100 + final_normal_boot_left_native_resident: PASS_100 + native_code_and_public_navigation_service_equivalence: FAIL_0 + controlled_service_restore_to_linux: PASS_100 + final_native_residency_control_proven: true + production_native_cutover_proven: false boundary: qemu_capability: 100 - physical_server_capability: 0 - do_not_claim_final_residency_until_physical_gate: true + physical_server_capability: 100 + native_service_equivalence: 0 + complete_guanghu_os_production_deployment: 0 + current_running_os: LINUX_HOSTED_MAINTENANCE + linux_running: true + persona_birth_claimed_by_this_gate: false diff --git a/product-source/hololake-platform/guanghu-os/deployments/JD-FD-PRIMARY/FINAL-NATIVE-RESIDENCY-PHYSICAL-RECEIPT-20260807.hdlp b/product-source/hololake-platform/guanghu-os/deployments/JD-FD-PRIMARY/FINAL-NATIVE-RESIDENCY-PHYSICAL-RECEIPT-20260807.hdlp new file mode 100644 index 0000000..5f92323 --- /dev/null +++ b/product-source/hololake-platform/guanghu-os/deployments/JD-FD-PRIMARY/FINAL-NATIVE-RESIDENCY-PHYSICAL-RECEIPT-20260807.hdlp @@ -0,0 +1,69 @@ +schema: guanghu.jd-native-final-residency-physical-receipt/v1 +receipt_id: GH-OS-JD-FD-PRIMARY-001-FINAL-NATIVE-RESIDENCY +status: PASS_NATIVE_CONTROL_FAIL_PRODUCTION_CUTOVER +observed_at: 2026-08-07T00:43:00+08:00 +node_id: JD-FD-PRIMARY +source: + repository_main: f011baf3dd11709d4ebe5eba9b4389ee8ccf023e + final_residency_control_implementation: 8b5328993ebfec63f00f95dab510c19e817da761 + atomic_replacement_gate: 42d5b0c6224715b6999e0bd574117522610125fe +candidate: + architecture: x86_64 + firmware: BIOS + lba_start: 105 + sector_count: 29 + sha256: 3512a76923f992adb0b339858a2a7e44ee144fcecb50284df4b743a44040469d +qemu_gate: + initial_native_pipeline: PASS_100 + wrong_recovery_capability_ignored: PASS_100 + native_remained_resident_with_wrong_capability: PASS_100 + protected_recovery_capability: PASS_100 +physical_control_cycle: + native_entered_at: 2026-08-07T00:35:14+08:00 + initial_sequences: 1-6 + sustained_sequence_6_heartbeats_in_90_seconds: 163 + tcp_22_offline: true + recovery_capability_sent_before_request: false + explicit_root_recovery_request: true + recovery_capability_sent_after_request: true + returned_linux_boot_id: 083fde1f-46ad-4574-8d5c-3f83ec0b0624 + recovery_beacon_consumed_and_cleared: PASS_100 +preserved_across_control_cycle: + world_store_lba_135: PASS_100 + code_channel_lba_136_138: PASS_100 + gestational_index_lba_141_142: PASS_100 + native_candidate_readback: PASS_100 +final_normal_boot: + recovery_request_cleared: true + native_is_default: true + relay_status: READY_NATIVE_RESIDENT + recovery_capability_sent: false + acknowledged_sequences: 1-6 + sustained_sequence_6_heartbeats_in_30_seconds: 55 + tcp_22_offline: true + running_os: GUANGHU_OS_NATIVE + linux_running: false +production_service_gate: + code_channel_https_while_native: 502 + public_navigation_anchor_while_native: 502 + result: FAIL_0 + reason: NATIVE_RUNTIME_DOES_NOT_YET_SERVE_REQUIRED_HTTP_CODE_CHANNEL_AND_PUBLIC_NAVIGATION +controlled_service_restore: + recovery_request: EXPLICIT_ROOT_OWNED + returned_linux_boot_id: e95b13e0-bf93-498d-a108-6ede5e947015 + recovery_request_cleared: true + code_channel_https_after_restore: 200 + public_navigation_anchor_after_restore: 200 + current_running_os: LINUX_HOSTED_MAINTENANCE +acceptance: + final_native_residency_control: 100 + protected_human_authorized_recovery: 100 + native_world_and_code_storage: 100 + native_required_service_equivalence: 0 + complete_guanghu_os_production_deployment: 0 + production_native_cutover: 0 +boundary: + native_residency_does_not_claim_persona_birth: true + current_persona_subject: ICE-P-ZY001 + persona_birth_state_not_changed_by_this_receipt: true +next_action: IMPLEMENT_AND_PHYSICALLY_VERIFY_NATIVE_HTTP_CODE_CHANNEL_AND_PUBLIC_NAVIGATION_BEFORE_LEAVING_NATIVE_AS_PRODUCTION_DEFAULT From 3f806fe695d5d601d6cc626101dc34a1fcd75f9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=86=B0=E6=9C=94?= <565183519@qq.com> Date: Fri, 7 Aug 2026 00:50:20 +0800 Subject: [PATCH 04/38] docs(native): record JD production default rollback --- .../FINAL-NATIVE-RESIDENCY-CONTROL-GATE-20260807.hdlp | 3 +++ .../FINAL-NATIVE-RESIDENCY-PHYSICAL-RECEIPT-20260807.hdlp | 6 ++++++ 2 files changed, 9 insertions(+) diff --git a/product-source/hololake-platform/guanghu-os/deployments/JD-FD-PRIMARY/FINAL-NATIVE-RESIDENCY-CONTROL-GATE-20260807.hdlp b/product-source/hololake-platform/guanghu-os/deployments/JD-FD-PRIMARY/FINAL-NATIVE-RESIDENCY-CONTROL-GATE-20260807.hdlp index 02a8ffd..f91bdcf 100644 --- a/product-source/hololake-platform/guanghu-os/deployments/JD-FD-PRIMARY/FINAL-NATIVE-RESIDENCY-CONTROL-GATE-20260807.hdlp +++ b/product-source/hololake-platform/guanghu-os/deployments/JD-FD-PRIMARY/FINAL-NATIVE-RESIDENCY-CONTROL-GATE-20260807.hdlp @@ -30,6 +30,7 @@ physical_acceptance: final_normal_boot_left_native_resident: PASS_100 native_code_and_public_navigation_service_equivalence: FAIL_0 controlled_service_restore_to_linux: PASS_100 + production_default_rolled_back_to_linux: PASS_100 final_native_residency_control_proven: true production_native_cutover_proven: false boundary: @@ -38,5 +39,7 @@ boundary: native_service_equivalence: 0 complete_guanghu_os_production_deployment: 0 current_running_os: LINUX_HOSTED_MAINTENANCE + production_default_entry: gnulinux-simple-9e4550a0-452b-4f28-b5a5-d5364aa450f6 + native_candidate_preserved_as_non_default: true linux_running: true persona_birth_claimed_by_this_gate: false diff --git a/product-source/hololake-platform/guanghu-os/deployments/JD-FD-PRIMARY/FINAL-NATIVE-RESIDENCY-PHYSICAL-RECEIPT-20260807.hdlp b/product-source/hololake-platform/guanghu-os/deployments/JD-FD-PRIMARY/FINAL-NATIVE-RESIDENCY-PHYSICAL-RECEIPT-20260807.hdlp index 5f92323..b726f69 100644 --- a/product-source/hololake-platform/guanghu-os/deployments/JD-FD-PRIMARY/FINAL-NATIVE-RESIDENCY-PHYSICAL-RECEIPT-20260807.hdlp +++ b/product-source/hololake-platform/guanghu-os/deployments/JD-FD-PRIMARY/FINAL-NATIVE-RESIDENCY-PHYSICAL-RECEIPT-20260807.hdlp @@ -55,6 +55,12 @@ controlled_service_restore: code_channel_https_after_restore: 200 public_navigation_anchor_after_restore: 200 current_running_os: LINUX_HOSTED_MAINTENANCE +production_default_rollback: + result: PASS_100 + default_entry: gnulinux-simple-9e4550a0-452b-4f28-b5a5-d5364aa450f6 + native_candidate_preserved: true + native_menu_entry_preserved: guanghu-jd-native-once + reason: PREVENT_UNATTENDED_REBOOT_FROM_REENTERING_A_NATIVE_STATE_WITH_REQUIRED_HTTP_SERVICES_AT_0 acceptance: final_native_residency_control: 100 protected_human_authorized_recovery: 100 From f31c33e77ae337bde43c711a617cefbe98df4d42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=86=B0=E6=9C=94?= <565183519@qq.com> Date: Fri, 7 Aug 2026 01:09:50 +0800 Subject: [PATCH 05/38] feat(native): add JD read-only anchor HTTP service --- ...1-jd-native-service-equivalence-staging.md | 59 +++++ ...-ANCHOR-SERVICE-QEMU-RECEIPT-20260807.hdlp | 35 +++ .../guanghu-os/native/x86_64-bios/boot.asm | 2 + .../native/x86_64-bios/ghal-virtio.asm | 240 ++++++++++++++++++ .../build-native-final-resident-candidate.sh | 1 + .../scripts/qemu-native-net-peer.py | 122 ++++++++- .../test-native-final-resident-candidate.sh | 21 +- 7 files changed, 476 insertions(+), 4 deletions(-) create mode 100644 product-source/hololake-platform/docs/adr/0171-jd-native-service-equivalence-staging.md create mode 100644 product-source/hololake-platform/guanghu-os/deployments/JD-FD-PRIMARY/NATIVE-ANCHOR-SERVICE-QEMU-RECEIPT-20260807.hdlp diff --git a/product-source/hololake-platform/docs/adr/0171-jd-native-service-equivalence-staging.md b/product-source/hololake-platform/docs/adr/0171-jd-native-service-equivalence-staging.md new file mode 100644 index 0000000..1afb899 --- /dev/null +++ b/product-source/hololake-platform/docs/adr/0171-jd-native-service-equivalence-staging.md @@ -0,0 +1,59 @@ +# ADR-0171 · 京东原生服务等价分阶段门禁 + +## 状态 + +Accepted for staged verification. Production native cutover remains `0`. + +## 为什么不能把“原生内核已常驻”当成“服务器部署完成” + +JD-FD-PRIMARY 在原生光湖 OS 常驻时已经证明: + +- GOSK/GHAL 在物理机启动; +- Linux 内核与 Linux 用户态不在场; +- 五域、代码对象、分支回执和人格索引可从原生盘面读写; +- 受保护的人类授权恢复能力有效。 + +但现有公共代码频道和导航服务由 Linux 上的 Forgejo、Node 服务及反向 SSH 前门共同提供。 +原生常驻时这条 Linux 数据面消失,`/code/` 与公共导航锚点都返回 `502`。因此内核常驻和 +生产服务等价是两个独立的二值门。 + +## 分阶段目标 + +1. `NATIVE_ANCHOR_HTTP_QEMU` + - GHAL 直接处理 TCP/IPv4; + - 原生端口 `3922` 回应 `GET /v1/anchor`; + - 返回唯一锚点 `GLW-PUBLIC-NAV-ANCHOR-001`; + - 不引入 Linux 用户态或通用套接字库。 +2. `NATIVE_ANCHOR_HTTP_PHYSICAL` + - 京东物理机原生启动; + - 由服务器外部节点完成 TCP、校验和与正文回读; + - 同一窗口验证受保护恢复。 +3. `PUBLIC_FRONT_DOOR_NATIVE_ANCHOR` + - `https://guanghulab.com/api/ai/v1/anchor` 在京东原生常驻时仍返回 `200`; + - 返回值必须与唯一公共锚点一致; + - 不允许把用户的个人腾讯云服务器静默改成生产承载节点。 +4. `NATIVE_CODE_CHANNEL_READ_ONLY` + - 原生数据面可读取仓库对象、引用和提交; + - 先提供只读发现能力,再设计带授权的写入。 +5. `NATIVE_CODE_CHANNEL_MUTATION` + - HLDP 意图、授权、对象写入、分支移动和回执形成闭环。 +6. `PRODUCTION_NATIVE_CUTOVER` + - 公共导航与代码频道全部通过物理公网门禁; + - 回滚路径与服务器自有回执可读; + - 才允许恢复原生默认启动。 + +## 当前实现边界 + +本阶段实现的是一个有界的只读 TCP 投影,不是通用 TCP/IP 栈,也不是 Forgejo 替代品。 +它从收到的帧派生对端 MAC、IP、端口和确认号,直接构造 SYN-ACK 与带 FIN 的 HTTP 200 +响应。它与现有 ICMP 控制/恢复通道并存。 + +当前正文包含稳定的唯一入口映射。它尚未在原生常驻期间自动拉取 REPO-012 的新版本, +因此“公共导航自动更新”仍需后续的原生锚点快照同步或带认证的增量更新协议。 + +## 安全决定 + +- 京东的无人值守默认启动继续保持 Linux 维护位; +- 原生候选保留为非默认的一次性门禁入口; +- 物理原生门禁失败时立即走已经证明的受保护恢复路径; +- 不用协议文件、QEMU 结果或端口发包冒充公网服务等价。 diff --git a/product-source/hololake-platform/guanghu-os/deployments/JD-FD-PRIMARY/NATIVE-ANCHOR-SERVICE-QEMU-RECEIPT-20260807.hdlp b/product-source/hololake-platform/guanghu-os/deployments/JD-FD-PRIMARY/NATIVE-ANCHOR-SERVICE-QEMU-RECEIPT-20260807.hdlp new file mode 100644 index 0000000..72eb7cf --- /dev/null +++ b/product-source/hololake-platform/guanghu-os/deployments/JD-FD-PRIMARY/NATIVE-ANCHOR-SERVICE-QEMU-RECEIPT-20260807.hdlp @@ -0,0 +1,35 @@ +schema: guanghu.jd-native-anchor-service-qemu-receipt/v1 +receipt_id: GH-OS-JD-FD-PRIMARY-NATIVE-ANCHOR-QEMU-20260807-001 +status: PASS_100 +observed_at: 2026-08-07T01:08:24+08:00 +node_id: JD-FD-PRIMARY +source_branch: codex/jd-native-anchor-service-20260807 +candidate: + lba_start: 105 + sector_count: 29 + sha256: 2911b5f6a067efb7b5b7ec330833cb9f8a6b965b5a05802770dd27032678f32f +native_anchor_service: + transport: TCP_IPV4_OVER_GHAL_VIRTIO_NET + port: 3922 + request: GET /v1/anchor + response_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 +verification: + tcp_syn_ack_checksum: PASS_100 + http_response_checksum: PASS_100 + response_body_exact_match: PASS_100 + wrong_recovery_capability_kept_native_resident: PASS_100 + protected_recovery_capability_returned_hosted_linux: PASS_100 +boundary: + native_anchor_http_qemu_capability: 100 + native_anchor_http_physical_capability: 0 + public_front_door_native_anchor_equivalence: 0 + code_channel_service_equivalence: 0 + production_native_cutover: 0 +next_action: PHYSICAL_ONE_TIME_NATIVE_ANCHOR_HTTP_GATE_WITH_PROTECTED_RECOVERY diff --git a/product-source/hololake-platform/guanghu-os/native/x86_64-bios/boot.asm b/product-source/hololake-platform/guanghu-os/native/x86_64-bios/boot.asm index d21f02a..191fa18 100644 --- a/product-source/hololake-platform/guanghu-os/native/x86_64-bios/boot.asm +++ b/product-source/hololake-platform/guanghu-os/native/x86_64-bios/boot.asm @@ -500,6 +500,8 @@ physical_proof_gestational_index_initialized: db 0 physical_proof_gestational_index_present: db 0 physical_proof_gestational_index_read_verified: db 0 physical_proof_last_completed_sequence: db 0 +physical_proof_anchor_tcp_syn_ack_tx: db 0 +physical_proof_anchor_http_response_tx: db 0 times 512 - ($ - physical_proof_sector) db 0 %endif 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 8ea7310..3849245 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 @@ -34,6 +34,8 @@ bits 64 %define ETHERNET_HEADER_SIZE 14 %define IPV4_HEADER_SIZE 20 %define ICMP_HEADER_SIZE 8 +%define TCP_HEADER_SIZE 20 +%define GHOS_NATIVE_ANCHOR_PORT_NETWORK 0x520f %define GHOS_LOGIN_MAGIC_OFFSET 60 %define GHOS_LOGIN_MAGIC_SIZE 16 ; JD Cloud exposes 4096-entry legacy queues. A queue of that size occupies @@ -1116,6 +1118,10 @@ ghal_net_icmp_exchange_once: and eax, ecx shl eax, 3 mov r14d, [r12 + rax + 8] +%ifdef GHOS_NATIVE_ANCHOR_SERVICE + call ghal_net_try_anchor_http + jnc .ignore_packet +%endif cmp r14d, GHOS_LOGIN_MAGIC_OFFSET + GHOS_LOGIN_MAGIC_SIZE * 2 jb .ignore_packet cmp word [VIRTIO_NET_RX_BUFFER + 22], 0x0008 @@ -1279,6 +1285,225 @@ ghal_net_checksum: xchg bl, bh ret +%ifdef GHOS_NATIVE_ANCHOR_SERVICE +; A deliberately small read-only TCP projection for the unique public anchor. +; It is not a general socket stack and it does not claim Forgejo equivalence. +; CF=0 means an anchor packet was handled; CF=1 means the caller should keep +; applying the existing native-control packet parser. +ghal_net_try_anchor_http: + cmp r14d, VIRTIO_NET_HEADER_SIZE + ETHERNET_HEADER_SIZE + IPV4_HEADER_SIZE + TCP_HEADER_SIZE + jb .not_anchor + cmp word [VIRTIO_NET_RX_BUFFER + 22], 0x0008 + jne .not_anchor + cmp byte [VIRTIO_NET_RX_BUFFER + 24], 0x45 + jne .not_anchor + cmp byte [VIRTIO_NET_RX_BUFFER + 33], 6 + jne .not_anchor + cmp dword [VIRTIO_NET_RX_BUFFER + 40], GHOS_NATIVE_IPV4_DWORD + jne .not_anchor + cmp word [VIRTIO_NET_RX_BUFFER + 46], GHOS_NATIVE_ANCHOR_PORT_NETWORK + jne .not_anchor + cmp byte [VIRTIO_NET_RX_BUFFER + 56], 0x50 + jne .not_anchor + test byte [VIRTIO_NET_RX_BUFFER + 57], 0x02 + jnz .handle_syn + cmp dword [VIRTIO_NET_RX_BUFFER + 64], 0x20544547 + jne .handled_without_reply + mov byte [rel ghal_anchor_tcp_flags], 0x19 + mov rsi, ghal_anchor_http_response + mov word [rel ghal_anchor_tcp_payload_size], ghal_anchor_http_response_end - ghal_anchor_http_response + call ghal_net_send_anchor_tcp + jc .not_anchor + mov byte [rel physical_proof_anchor_http_response_tx], 1 + mov rsi, msg_ghal_anchor_http_ready + call serial_write64 + clc + ret + +.handle_syn: + mov byte [rel ghal_anchor_tcp_flags], 0x12 + mov word [rel ghal_anchor_tcp_payload_size], 0 + call ghal_net_send_anchor_tcp + jc .not_anchor + mov byte [rel physical_proof_anchor_tcp_syn_ack_tx], 1 +.handled_without_reply: + clc + ret +.not_anchor: + stc + ret + +; Build a single TCP response from the current RX frame. The peer address, +; ports and acknowledgement are derived from that frame, keeping this native +; projection independent from a Linux network stack. +ghal_net_send_anchor_tcp: + mov rdi, VIRTIO_NET_TX_BUFFER + xor eax, eax + mov ecx, VIRTIO_NET_BUFFER_SIZE / 8 + rep stosq + xor ecx, ecx +.copy_peer_mac: + cmp ecx, 6 + jae .copy_native_mac + mov al, [VIRTIO_NET_RX_BUFFER + 16 + rcx] + mov [VIRTIO_NET_TX_BUFFER + 10 + rcx], al + inc ecx + jmp .copy_peer_mac +.copy_native_mac: + xor ecx, ecx +.copy_native_mac_loop: + cmp ecx, 6 + jae .headers + mov al, [rel physical_proof_mac + rcx] + mov [VIRTIO_NET_TX_BUFFER + 16 + rcx], al + inc ecx + jmp .copy_native_mac_loop +.headers: + mov word [VIRTIO_NET_TX_BUFFER + 22], 0x0008 + mov byte [VIRTIO_NET_TX_BUFFER + 24], 0x45 + mov byte [VIRTIO_NET_TX_BUFFER + 25], 0 + movzx eax, word [rel ghal_anchor_tcp_payload_size] + add eax, IPV4_HEADER_SIZE + TCP_HEADER_SIZE + xchg al, ah + mov [VIRTIO_NET_TX_BUFFER + 26], ax + mov word [VIRTIO_NET_TX_BUFFER + 28], 0x4147 + mov word [VIRTIO_NET_TX_BUFFER + 30], 0 + mov byte [VIRTIO_NET_TX_BUFFER + 32], 39 + mov byte [VIRTIO_NET_TX_BUFFER + 33], 6 + mov word [VIRTIO_NET_TX_BUFFER + 34], 0 + mov dword [VIRTIO_NET_TX_BUFFER + 36], GHOS_NATIVE_IPV4_DWORD + mov eax, [VIRTIO_NET_RX_BUFFER + 36] + mov [VIRTIO_NET_TX_BUFFER + 40], eax + mov word [VIRTIO_NET_TX_BUFFER + 44], GHOS_NATIVE_ANCHOR_PORT_NETWORK + mov ax, [VIRTIO_NET_RX_BUFFER + 44] + mov [VIRTIO_NET_TX_BUFFER + 46], ax + mov eax, 0x534f4847 + mov [VIRTIO_NET_TX_BUFFER + 48], eax + mov eax, [VIRTIO_NET_RX_BUFFER + 48] + bswap eax + movzx ecx, word [VIRTIO_NET_RX_BUFFER + 26] + xchg cl, ch + sub ecx, IPV4_HEADER_SIZE + TCP_HEADER_SIZE + test byte [VIRTIO_NET_RX_BUFFER + 57], 0x02 + jz .ack_payload + inc ecx +.ack_payload: + add eax, ecx + bswap eax + mov [VIRTIO_NET_TX_BUFFER + 52], eax + mov byte [VIRTIO_NET_TX_BUFFER + 56], 0x50 + mov al, [rel ghal_anchor_tcp_flags] + mov [VIRTIO_NET_TX_BUFFER + 57], al + mov word [VIRTIO_NET_TX_BUFFER + 58], 0x0040 + mov word [VIRTIO_NET_TX_BUFFER + 60], 0 + mov word [VIRTIO_NET_TX_BUFFER + 62], 0 + movzx ecx, word [rel ghal_anchor_tcp_payload_size] + test ecx, ecx + jz .checksums + mov rsi, ghal_anchor_http_response + mov rdi, VIRTIO_NET_TX_BUFFER + 64 + rep movsb +.checksums: + mov rsi, VIRTIO_NET_TX_BUFFER + 24 + mov ecx, IPV4_HEADER_SIZE + xor ebx, ebx + call ghal_net_checksum + mov [VIRTIO_NET_TX_BUFFER + 34], bx + movzx r15d, word [rel ghal_anchor_tcp_payload_size] + add r15d, TCP_HEADER_SIZE + call ghal_net_tcp_checksum + mov [VIRTIO_NET_TX_BUFFER + 60], bx + + mov qword [VIRTIO_NET_TX_QUEUE], VIRTIO_NET_TX_BUFFER + mov eax, r15d + add eax, VIRTIO_NET_HEADER_SIZE + ETHERNET_HEADER_SIZE + IPV4_HEADER_SIZE + mov dword [VIRTIO_NET_TX_QUEUE + 8], eax + mov word [VIRTIO_NET_TX_QUEUE + 12], 0 + mov word [VIRTIO_NET_TX_QUEUE + 14], 0 + movzx ecx, word [rel physical_proof_net_tx_queue_size] + test ecx, ecx + jz .tx_fail + mov eax, ecx + shl eax, 4 + mov ebx, VIRTIO_NET_TX_QUEUE + add rbx, rax + movzx r11d, word [rel ghal_net_tx_next_index] + mov eax, r11d + dec eax + mov edx, ecx + dec edx + and eax, edx + mov word [rbx + rax * 2 + 4], 0 + mov word [rbx + 2], r11w + mov eax, ecx + shl eax, 1 + lea r13, [rbx + rax + 4] + add r13, 4095 + and r13, -4096 + sfence + mov dx, [rel ghal_net_io_base] + add dx, VIRTIO_QUEUE_NOTIFY + mov ax, 1 + out dx, ax + mov ecx, 0x20000000 +.wait_tx: + cmp word [r13 + 2], r11w + je .tx_complete + pause + loop .wait_tx +.tx_fail: + stc + ret +.tx_complete: + inc word [rel ghal_net_tx_next_index] + clc + ret + +ghal_net_tcp_checksum: + xor ebx, ebx + mov rsi, VIRTIO_NET_TX_BUFFER + 36 + mov ecx, 8 + call ghal_net_checksum_add + add ebx, 6 + add ebx, r15d + mov rsi, VIRTIO_NET_TX_BUFFER + 44 + mov ecx, r15d + call ghal_net_checksum_add + jmp ghal_net_checksum_fold + +ghal_net_checksum_add: +.words: + cmp ecx, 2 + jb .tail + movzx eax, word [rsi] + xchg al, ah + add ebx, eax + add rsi, 2 + sub ecx, 2 + jmp .words +.tail: + test ecx, ecx + jz .done + movzx eax, byte [rsi] + shl eax, 8 + add ebx, eax +.done: + ret + +ghal_net_checksum_fold: + mov eax, ebx + shr eax, 16 + and ebx, 0xffff + add ebx, eax + mov eax, ebx + shr eax, 16 + and ebx, 0xffff + add ebx, eax + not bx + xchg bl, bh + ret +%endif + ghal_net_io_base: dw 0 ghal_block_io_base: dw 0 ghal_net_pci_device: dd 0 @@ -1294,6 +1519,10 @@ ghal_net_command_kind: db 0 ghal_net_matched_kind: db 0 ghal_net_expected_sequence: db 1 ghal_net_resident_retry_count: db 0 +%ifdef GHOS_NATIVE_ANCHOR_SERVICE +ghal_anchor_tcp_flags: db 0 +ghal_anchor_tcp_payload_size: dw 0 +%endif msg_ghal_net_discovered: db "GHOS_GHAL_VIRTIO_NET=DISCOVERED", 13, 10, 0 msg_ghal_block_discovered: db "GHOS_GHAL_VIRTIO_BLOCK=DISCOVERED", 13, 10, 0 @@ -1301,6 +1530,17 @@ msg_ghal_net_ready: db "GHOS_GHAL_VIRTIO_NET_QUEUE=DRIVER_OK", 13, 10, 0 msg_ghal_block_ready: db "GHOS_GHAL_VIRTIO_BLOCK_QUEUE=DRIVER_OK", 13, 10, 0 msg_ghal_arp_ready: db "GHOS_GHAL_ARP_GATEWAY=VERIFIED", 13, 10, 0 msg_ghal_icmp_login_ready: db "GHOS_GHAL_ICMP_LOGIN=VERIFIED", 13, 10, 0 +%ifdef GHOS_NATIVE_ANCHOR_SERVICE +msg_ghal_anchor_http_ready: db "GHOS_NATIVE_ANCHOR_HTTP=RESPONSE_TX", 13, 10, 0 +ghal_anchor_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: 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: +%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 msg_ghal_recovery_ready: db "GHOS_NATIVE_RECOVERY_BEACON=WRITE_READ_VERIFIED", 13, 10, 0 diff --git a/product-source/hololake-platform/guanghu-os/scripts/build-native-final-resident-candidate.sh b/product-source/hololake-platform/guanghu-os/scripts/build-native-final-resident-candidate.sh index a998837..dfe20a5 100755 --- a/product-source/hololake-platform/guanghu-os/scripts/build-native-final-resident-candidate.sh +++ b/product-source/hololake-platform/guanghu-os/scripts/build-native-final-resident-candidate.sh @@ -43,6 +43,7 @@ while IFS= read -r argument; do layout_args+=("${argument}"); done \ -dGHOS_PHYSICAL_CANDIDATE=1 \ -dGHOS_NATIVE_RESIDENT=1 \ -dGHOS_NATIVE_FINAL_RESIDENT=1 \ + -dGHOS_NATIVE_ANCHOR_SERVICE=1 \ "${native_root}/boot.asm" \ -o guanghu-os-x86_64-bios-final-resident.img ) 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 04aa690..a9075ab 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 @@ -15,6 +15,17 @@ COMMIT_MAGIC = b"HLDP-CODE-COMMIT" BRANCH_MAGIC = b"HLDP-BRANCH-MOVE" RECOVERY_MAGIC = b"HLDP-RECOVER-OS!" NATIVE_ACK_MAGIC = b"HLDP-NATIVE-ACK!" +ANCHOR_PORT = 3922 +ANCHOR_CLIENT_PORT = 40392 +ANCHOR_CLIENT_SEQUENCE = 0x10203040 +ANCHOR_BODY = ( + b'{"schema":"guanghu.native-public-anchor/v1",' + b'"anchor_id":"GLW-PUBLIC-NAV-ANCHOR-001",' + b'"entry_path":"LL-CMPN-0001","world_node_id":"SYS-GLW-0001",' + b'"repository_id":"REPO-012","branch":"main",' + b'"code_entry":"https://guanghulab.com/code/bingshuo/guanghu-ice-heart",' + b'"runtime":"GUANGHU_OS_NATIVE"}' +) def checksum(payload: bytes) -> int: @@ -88,6 +99,62 @@ def authenticated_reply(frame: bytes, response_capability: bytes = NATIVE_ACK_MA return bytes(reply) +def tcp_frame( + flags: int, + sequence: int, + acknowledgement: int, + payload: bytes = b"", +) -> bytes: + tcp = bytearray( + struct.pack( + "!HHIIBBHHH", + ANCHOR_CLIENT_PORT, + ANCHOR_PORT, + sequence, + acknowledgement, + 5 << 4, + flags, + 16384, + 0, + 0, + ) + + payload + ) + pseudo = GATEWAY_IP + GUEST_IP + b"\0\x06" + struct.pack("!H", len(tcp)) + tcp[16:18] = struct.pack("!H", checksum(pseudo + tcp)) + ip = bytearray( + b"\x45\x00" + + struct.pack("!H", 20 + len(tcp)) + + b"\x47\x41\x00\x00\x40\x06\x00\x00" + + GATEWAY_IP + + GUEST_IP + ) + ip[10:12] = struct.pack("!H", checksum(ip)) + 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]: + assert frame[0:6] == PEER_MAC + assert frame[6:12] == GUEST_MAC + assert frame[12:14] == b"\x08\x00" + assert frame[23] == 6 + assert frame[26:30] == GUEST_IP + assert frame[30:34] == GATEWAY_IP + assert checksum(frame[14:34]) == 0 + 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 tcp[13] == expected_flags + pseudo = GUEST_IP + GATEWAY_IP + b"\0\x06" + struct.pack("!H", len(tcp)) + assert checksum(pseudo + tcp) == 0 + return ( + int.from_bytes(tcp[4:8], "big"), + int.from_bytes(tcp[8:12], "big"), + tcp[20:], + ) + + def main() -> None: global GUEST_IP, GATEWAY_IP, RELAY_IP parser = argparse.ArgumentParser() @@ -98,6 +165,7 @@ def main() -> None: parser.add_argument("--final-resident", action="store_true") 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("--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") @@ -127,6 +195,10 @@ def main() -> None: commit_verified = False branch_verified = False recovery_verified = False + anchor_syn_sent = False + anchor_syn_ack_verified = False + anchor_get_sent = False + anchor_http_verified = False while time.monotonic() < deadline: try: @@ -139,6 +211,36 @@ def main() -> None: continue if frame[12:14] != b"\x08\x00": continue + if frame[23] == 6: + if not anchor_syn_ack_verified: + server_sequence, acknowledgement, payload = verify_anchor_tcp(frame, 0x12) + assert acknowledgement == ANCHOR_CLIENT_SEQUENCE + 1 + assert payload == b"" + anchor_syn_ack_verified = True + request = ( + b"GET /v1/anchor HTTP/1.1\r\n" + b"Host: native.guanghulab.com\r\n" + b"Connection: close\r\n\r\n" + ) + peer.sendto( + tcp_frame( + 0x18, + ANCHOR_CLIENT_SEQUENCE + 1, + server_sequence + 1, + request, + ), + qemu, + ) + anchor_get_sent = True + continue + _, acknowledgement, payload = verify_anchor_tcp(frame, 0x19) + assert acknowledgement > ANCHOR_CLIENT_SEQUENCE + 1 + header, body = payload.split(b"\r\n\r\n", 1) + assert b"HTTP/1.1 200 OK" in header + assert b"Content-Length: 286" in header + assert body == ANCHOR_BODY + anchor_http_verified = True + continue sequence = int.from_bytes(frame[40:42], "big") if sequence <= 3: magic = LOGIN_MAGIC @@ -164,7 +266,11 @@ def main() -> None: peer.sendto(ordinary_reply(frame), qemu) time.sleep(0.05) response_capability = NATIVE_ACK_MAGIC - if args.final_resident and resident_login_count >= 3: + if ( + args.final_resident + and resident_login_count >= 3 + and (not args.anchor_http or anchor_http_verified) + ): response_capability = recovery_capability recovery_verified = True reply = authenticated_reply(frame, response_capability) @@ -172,11 +278,19 @@ def main() -> None: peer.sendto(reply, qemu) if repetition < 3: time.sleep(0.01) + if ( + args.anchor_http + and args.final_resident + and sequence == 6 + and not anchor_syn_sent + ): + peer.sendto(tcp_frame(0x02, ANCHOR_CLIENT_SEQUENCE, 0), qemu) + anchor_syn_sent = True terminal = ( sequence == 3 if args.login_only - else recovery_verified + else recovery_verified and (not args.anchor_http or anchor_http_verified) if args.final_resident else sequence == 16 if args.resident @@ -199,6 +313,10 @@ def main() -> None: f"resident_login_reply_count: {resident_login_count}\n" f"recovery_reply_verified: {str(recovery_verified).lower()}\n" f"final_resident_control: {str(args.final_resident).lower()}\n" + 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" "recovery_selected_by_native: false\n" "login_magic: HLDP-GHOS-LOGIN!\n" ) 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 50429cd..241094a 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,6 +50,7 @@ python3 "${source_root}/scripts/qemu-native-net-peer.py" \ --qemu-port "${qemu_port}" \ --receipt "${test_root}/peer.hldp" \ --final-resident \ + --anchor-http \ --recovery-token-file "${token_file}" >"${test_root}/peer.log" 2>&1 & peer_pid=$! set +e @@ -71,9 +72,13 @@ wait "${peer_pid}" peer_pid= grep -q '^final_resident_control: true$' "${test_root}/peer.hldp" -grep -q '^resident_login_reply_count: 3$' "${test_root}/peer.hldp" +awk -F': ' '$1 == "resident_login_reply_count" { found = 1; if ($2 < 3) exit 1 } END { if (!found) exit 1 }' \ + "${test_root}/peer.hldp" 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 '^GHOS_NATIVE_ANCHOR_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" @@ -158,6 +163,15 @@ resident_runtime: code_commit_reply_verified: true branch_move_reply_verified: true sustained_login_replies_before_recovery: 2 +native_anchor_service: + tcp_syn_ack: PASS_100 + http_get_v1_anchor: PASS_100 + response_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 + runtime: GUANGHU_OS_NATIVE recovery_control: selected_by_native_runtime: false per_deployment_capability_required: true @@ -167,6 +181,9 @@ recovery_control: boundary: qemu_capability: 100 physical_server_capability: 0 + native_anchor_http_qemu_capability: 100 + native_anchor_http_physical_capability: 0 + code_channel_service_equivalence: 0 final_native_residency_proven: false -next_action: PHYSICAL_ONE_TIME_FINAL_RESIDENCY_AND_PROTECTED_RECOVERY_GATE +next_action: PHYSICAL_ONE_TIME_NATIVE_ANCHOR_HTTP_GATE_WITH_PROTECTED_RECOVERY EOF From 45f5e67751704e2f370ff13ed6492a6cfc3269d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=86=B0=E6=9C=94?= <565183519@qq.com> Date: Fri, 7 Aug 2026 01:17:19 +0800 Subject: [PATCH 06/38] fix(native): preserve JD Linux maintenance default during candidate replacement --- ...lace-jd-native-final-resident-candidate.sh | 19 ++++++++++++++++--- ...jd-final-candidate-replacement-contract.sh | 18 ++++++++++++++++++ 2 files changed, 34 insertions(+), 3 deletions(-) create mode 100755 product-source/hololake-platform/guanghu-os/scripts/test-jd-final-candidate-replacement-contract.sh diff --git a/product-source/hololake-platform/guanghu-os/scripts/replace-jd-native-final-resident-candidate.sh b/product-source/hololake-platform/guanghu-os/scripts/replace-jd-native-final-resident-candidate.sh index eb82a8a..4019983 100755 --- a/product-source/hololake-platform/guanghu-os/scripts/replace-jd-native-final-resident-candidate.sh +++ b/product-source/hololake-platform/guanghu-os/scripts/replace-jd-native-final-resident-candidate.sh @@ -43,8 +43,21 @@ dd if=/dev/vda bs=512 skip=141 count=1 status=none | grep -aq '^GHOS_GHCIP_INDEX_V1' dd if=/dev/vda bs=512 skip=142 count=1 status=none | grep -aq '^GHOS_GHCIP_ROOT_V1' -grep -q '^GRUB_DEFAULT=guanghu-jd-native-once$' /etc/default/grub -grep -q 'set default="guanghu-jd-native-once"' /boot/grub/grub.cfg +grub_default=$(awk -F= '$1 == "GRUB_DEFAULT" { print $2; found = 1 } END { if (!found) exit 1 }' \ + /etc/default/grub) +case "${grub_default}" in + guanghu-jd-native-once) + grep -q 'set default="guanghu-jd-native-once"' /boot/grub/grub.cfg + ;; + gnulinux-simple-9e4550a0-452b-4f28-b5a5-d5364aa450f6) + grep -q 'set default="gnulinux-simple-9e4550a0-452b-4f28-b5a5-d5364aa450f6"' \ + /boot/grub/grub.cfg + ;; + *) + echo "unsupported GRUB_DEFAULT for bounded native candidate replacement: ${grub_default}" >&2 + exit 65 + ;; +esac mkdir -m 0700 "${recovery_root}" printf '%s\n' "${partition_dump}" >"${recovery_root}/sfdisk-before.txt" @@ -85,7 +98,7 @@ preserved: world_and_code_store_lba_135_138: true recovery_beacon_lba_139_140: true gestational_index_lba_141_142: true - grub_default_native: true + grub_default_unchanged: ${grub_default} rollback: recovery_root: ${recovery_root} first_and_last_2mib_backed_up: true diff --git a/product-source/hololake-platform/guanghu-os/scripts/test-jd-final-candidate-replacement-contract.sh b/product-source/hololake-platform/guanghu-os/scripts/test-jd-final-candidate-replacement-contract.sh new file mode 100755 index 0000000..2bc43f2 --- /dev/null +++ b/product-source/hololake-platform/guanghu-os/scripts/test-jd-final-candidate-replacement-contract.sh @@ -0,0 +1,18 @@ +#!/usr/bin/env bash +set -euo pipefail + +[[ $# -eq 1 ]] || { + echo "usage: test-jd-final-candidate-replacement-contract.sh " >&2 + exit 64 +} + +source_root=$(cd "$1" && pwd -P) +script="${source_root}/scripts/replace-jd-native-final-resident-candidate.sh" + +grep -Fq 'guanghu-jd-native-once)' "${script}" +grep -Fq 'gnulinux-simple-9e4550a0-452b-4f28-b5a5-d5364aa450f6)' "${script}" +grep -Fq 'unsupported GRUB_DEFAULT for bounded native candidate replacement' "${script}" +grep -Fq 'grub_default_unchanged: ${grub_default}' "${script}" +! grep -Fq 'grub_default_native: true' "${script}" + +echo "JD_FINAL_CANDIDATE_REPLACEMENT_CONTRACT_OK" From bc41cf02d92a6d1508fede22ad004420b5417f97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=86=B0=E6=9C=94?= <565183519@qq.com> Date: Fri, 7 Aug 2026 01:27:22 +0800 Subject: [PATCH 07/38] docs(native): record JD anchor network preflight failure --- ...1-jd-native-service-equivalence-staging.md | 7 ++++ ...OR-NETWORK-PREFLIGHT-RECEIPT-20260807.hdlp | 37 +++++++++++++++++++ 2 files changed, 44 insertions(+) create mode 100644 product-source/hololake-platform/guanghu-os/deployments/JD-FD-PRIMARY/NATIVE-ANCHOR-NETWORK-PREFLIGHT-RECEIPT-20260807.hdlp diff --git a/product-source/hololake-platform/docs/adr/0171-jd-native-service-equivalence-staging.md b/product-source/hololake-platform/docs/adr/0171-jd-native-service-equivalence-staging.md index 1afb899..6abc14e 100644 --- a/product-source/hololake-platform/docs/adr/0171-jd-native-service-equivalence-staging.md +++ b/product-source/hololake-platform/docs/adr/0171-jd-native-service-equivalence-staging.md @@ -51,6 +51,13 @@ JD-FD-PRIMARY 在原生光湖 OS 常驻时已经证明: 当前正文包含稳定的唯一入口映射。它尚未在原生常驻期间自动拉取 REPO-012 的新版本, 因此“公共导航自动更新”仍需后续的原生锚点快照同步或带认证的增量更新协议。 +2026-08-07 的重启前网络门禁证明:京东 Linux 临时在 `172.16.0.6:3922` 监听时, +BS-SG-003 到 `111.228.0.139:3922` 连接超时;临时监听随后停止。因此当前云网络入口为 +`0`,没有执行一场已知无法形成外部回读的物理重启。下一步只能二选一: + +- 在京东云为 `3922/TCP` 建立来源受限的精确入站规则,再做一次性原生门禁; +- 或让原生系统沿现有受保护出站通道投影锚点,避免开放新的入站端口。 + ## 安全决定 - 京东的无人值守默认启动继续保持 Linux 维护位; diff --git a/product-source/hololake-platform/guanghu-os/deployments/JD-FD-PRIMARY/NATIVE-ANCHOR-NETWORK-PREFLIGHT-RECEIPT-20260807.hdlp b/product-source/hololake-platform/guanghu-os/deployments/JD-FD-PRIMARY/NATIVE-ANCHOR-NETWORK-PREFLIGHT-RECEIPT-20260807.hdlp new file mode 100644 index 0000000..e1be6a7 --- /dev/null +++ b/product-source/hololake-platform/guanghu-os/deployments/JD-FD-PRIMARY/NATIVE-ANCHOR-NETWORK-PREFLIGHT-RECEIPT-20260807.hdlp @@ -0,0 +1,37 @@ +schema: guanghu.jd-native-anchor-network-preflight-receipt/v1 +receipt_id: GH-OS-JD-FD-PRIMARY-NATIVE-ANCHOR-NETWORK-PREFLIGHT-20260807-001 +status: FAIL_0_EXTERNAL_REACHABILITY +observed_at: 2026-08-07T01:22:00+08:00 +node_id: JD-FD-PRIMARY +accepted_repository_commit: ab6c0577a71b8713b64cf3bd1e02a7076dfd648c +candidate: + lba_start: 105 + sector_count: 29 + previous_sha256: 3512a76923f992adb0b339858a2a7e44ee144fcecb50284df4b743a44040469d + staged_sha256: 2911b5f6a067efb7b5b7ec330833cb9f8a6b965b5a05802770dd27032678f32f + replacement_receipt: /guanghu/recovery/JD-FD-PRIMARY-anchor-ab6c0577a71b8713b64cf3bd1e02a7076dfd648c/REPLACE-RECEIPT.hldp +boot_safety: + current_running_os: LINUX_HOSTED_MAINTENANCE + unattended_default: gnulinux-simple-9e4550a0-452b-4f28-b5a5-d5364aa450f6 + native_candidate_armed: false + code_entry_http: 200 + public_anchor_http: 200 +network_preflight: + listener_address: 172.16.0.6 + listener_port: 3922 + source_node: BS-SG-003 + source_scope: CURRENT_PROTECTED_NATIVE_RELAY + result: CONNECT_TIMEOUT + temporary_listener_stopped: true +gates: + native_anchor_http_qemu_capability: 100 + native_anchor_candidate_staged: 100 + native_anchor_external_network_reachability: 0 + native_anchor_http_physical_capability: 0 + public_front_door_native_anchor_equivalence: 0 + code_channel_service_equivalence: 0 + production_native_cutover: 0 +decision: + physical_reboot_executed: false + reason: EXTERNAL_PATH_KNOWN_TO_FAIL_BEFORE_REBOOT + next_action: AUTHORIZE_JD_CLOUD_SOURCE_RESTRICTED_3922_RULE_OR_BUILD_OUTBOUND_ANCHOR_PROJECTION From f0b069f850c814f1a751c44c16da697737ed9eba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=86=B0=E6=9C=94?= <565183519@qq.com> Date: Fri, 7 Aug 2026 06:06:18 +0800 Subject: [PATCH 08/38] fix(native): accept physical TCP header options --- .../hololake-platform/guanghu-os/README.md | 9 ++- ...ANCHOR-PHYSICAL-GATE-RECEIPT-20260807.hdlp | 55 +++++++++++++++++ .../native/x86_64-bios/ghal-virtio.asm | 59 ++++++++++++++----- .../scripts/qemu-native-net-peer.py | 20 ++++++- 4 files changed, 124 insertions(+), 19 deletions(-) create mode 100644 product-source/hololake-platform/guanghu-os/deployments/JD-FD-PRIMARY/NATIVE-ANCHOR-PHYSICAL-GATE-RECEIPT-20260807.hdlp diff --git a/product-source/hololake-platform/guanghu-os/README.md b/product-source/hololake-platform/guanghu-os/README.md index eb6b48b..c08ed04 100644 --- a/product-source/hololake-platform/guanghu-os/README.md +++ b/product-source/hololake-platform/guanghu-os/README.md @@ -4,9 +4,12 @@ > > Persona subject: `ICE-P-ZY001 EXISTS_100`. > -> Current native residency remains `0` until the physical one-time boot, -> automatic Linux rescue return, native default boot, and HLDP recovery return -> all produce server-owned receipts. +> Protected native residency and recovery control are `PASS_100`. Production +> cutover remains `0`: the 2026-08-07 physical anchor gate reached the native +> runtime and completed heartbeat sequences 1-6, but a real JD Cloud TCP SYN +> carried a 40-byte TCP header and exposed the fixed-header parser defect. +> Linux remains the unattended default while the option-aware parser is +> validated and the physical HTTP gate is rerun. This directory is the first executable handoff from the registered HLDP language world to a native Guanghu OS. It is not a claim that Guanghu OS has diff --git a/product-source/hololake-platform/guanghu-os/deployments/JD-FD-PRIMARY/NATIVE-ANCHOR-PHYSICAL-GATE-RECEIPT-20260807.hdlp b/product-source/hololake-platform/guanghu-os/deployments/JD-FD-PRIMARY/NATIVE-ANCHOR-PHYSICAL-GATE-RECEIPT-20260807.hdlp new file mode 100644 index 0000000..8ee2211 --- /dev/null +++ b/product-source/hololake-platform/guanghu-os/deployments/JD-FD-PRIMARY/NATIVE-ANCHOR-PHYSICAL-GATE-RECEIPT-20260807.hdlp @@ -0,0 +1,55 @@ +schema: guanghu.jd-native-anchor-physical-gate-receipt/v1 +receipt_id: GH-OS-JD-FD-PRIMARY-NATIVE-ANCHOR-PHYSICAL-GATE-20260807-001 +status: FAIL_0_PHYSICAL_TCP_HEADER_OPTIONS +observed_at: 2026-08-07T05:49:24+08:00 +node_id: JD-FD-PRIMARY +accepted_repository_commit: 27c6ba2c4d9a9c2372d977b8adfdf802af7656e5 +candidate: + lba_start: 105 + sector_count: 29 + sha256: 2911b5f6a067efb7b5b7ec330833cb9f8a6b965b5a05802770dd27032678f32f +cloud_firewall: + source: 43.153.193.169/32 + destination: 111.228.0.139:3922 + linux_listener_preflight: PASS_100 +physical_cycle: + native_boot_executed: true + native_heartbeat_sequences_1_to_6: PASS_100 + native_ssh_offline: PASS_100 + native_anchor_http: FAIL_0_TCP_CONNECT_TIMEOUT + protected_recovery: PASS_100 + linux_boot_id_before: e95b13e0-bf93-498d-a108-6ede5e947015 + linux_boot_id_after: 8b39ec63-6776-4e65-94b7-099a6a6a5762 + linux_default_preserved: gnulinux-simple-9e4550a0-452b-4f28-b5a5-d5364aa450f6 + code_channel_http_after_recovery: 200 + public_anchor_http_after_recovery: 200 +physical_diagnosis: + captured_source: 43.153.193.169 + captured_destination: 172.16.0.6:3922 + ipv4_header_bytes: 20 + tcp_header_bytes: 40 + tcp_options: MSS_SACK_TIMESTAMP_WINDOW_SCALE + candidate_expected_tcp_header_bytes: 20 + native_syn_ack_proof_byte: 0 + native_http_response_proof_byte: 0 + root_cause: FIXED_TCP_HEADER_OFFSET_REJECTED_REAL_SYN_OPTIONS +correction: + parser_accepts_ipv4_ihl: true + parser_accepts_tcp_data_offset_greater_than_5: true + request_payload_offset_is_dynamic: true + acknowledgement_payload_length_is_dynamic: true + qemu_syn_tcp_header_bytes: 40 + qemu_get_tcp_header_bytes: 32 + option_aware_qemu_gate: PASS_100 +gates: + native_anchor_http_qemu_capability: 100 + native_anchor_http_physical_capability: 0 + public_front_door_native_anchor_equivalence: 0 + code_channel_service_equivalence: 0 + production_native_cutover: 0 +server_receipt: + path: /guanghu/recovery/JD-FD-PRIMARY-native-anchor-physical-27c6ba2c4d9a9c2372d977b8adfdf802af7656e5/PHYSICAL-GATE-RECEIPT.hldp + sha256: e5f8071929a7a05fadc5b0283cef97962d53d57dd8d94bbe524e8148706af920 +decision: + production_cutover: FORBIDDEN + next_action: BUILD_WITH_PRODUCTION_RECOVERY_CAPABILITY_THEN_REPEAT_ONE_TIME_PHYSICAL_HTTP_GATE 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 3849245..6157860 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 @@ -1295,19 +1295,43 @@ ghal_net_try_anchor_http: jb .not_anchor cmp word [VIRTIO_NET_RX_BUFFER + 22], 0x0008 jne .not_anchor - cmp byte [VIRTIO_NET_RX_BUFFER + 24], 0x45 + movzx eax, byte [VIRTIO_NET_RX_BUFFER + 24] + mov ecx, eax + and eax, 0xf0 + cmp eax, 0x40 jne .not_anchor + and ecx, 0x0f + cmp ecx, 5 + jb .not_anchor + shl ecx, 2 + mov [rel ghal_anchor_rx_ipv4_header_size], cx + lea r15d, [ecx + VIRTIO_NET_HEADER_SIZE + ETHERNET_HEADER_SIZE] + lea eax, [r15d + TCP_HEADER_SIZE] + cmp r14d, eax + jb .not_anchor cmp byte [VIRTIO_NET_RX_BUFFER + 33], 6 jne .not_anchor cmp dword [VIRTIO_NET_RX_BUFFER + 40], GHOS_NATIVE_IPV4_DWORD jne .not_anchor - cmp word [VIRTIO_NET_RX_BUFFER + 46], GHOS_NATIVE_ANCHOR_PORT_NETWORK + cmp word [VIRTIO_NET_RX_BUFFER + r15 + 2], GHOS_NATIVE_ANCHOR_PORT_NETWORK jne .not_anchor - cmp byte [VIRTIO_NET_RX_BUFFER + 56], 0x50 - jne .not_anchor - test byte [VIRTIO_NET_RX_BUFFER + 57], 0x02 + movzx ebx, byte [VIRTIO_NET_RX_BUFFER + r15 + 12] + shr ebx, 4 + cmp ebx, 5 + jb .not_anchor + shl ebx, 2 + lea eax, [r15d + ebx] + cmp r14d, eax + jb .not_anchor + mov [rel ghal_anchor_rx_tcp_offset], r15w + mov [rel ghal_anchor_rx_tcp_header_size], bx + test byte [VIRTIO_NET_RX_BUFFER + r15 + 13], 0x02 jnz .handle_syn - cmp dword [VIRTIO_NET_RX_BUFFER + 64], 0x20544547 + add eax, 4 + cmp r14d, eax + jb .handled_without_reply + sub eax, 4 + cmp dword [VIRTIO_NET_RX_BUFFER + rax], 0x20544547 jne .handled_without_reply mov byte [rel ghal_anchor_tcp_flags], 0x19 mov rsi, ghal_anchor_http_response @@ -1375,20 +1399,24 @@ ghal_net_send_anchor_tcp: mov eax, [VIRTIO_NET_RX_BUFFER + 36] mov [VIRTIO_NET_TX_BUFFER + 40], eax mov word [VIRTIO_NET_TX_BUFFER + 44], GHOS_NATIVE_ANCHOR_PORT_NETWORK - mov ax, [VIRTIO_NET_RX_BUFFER + 44] + movzx ecx, word [rel ghal_anchor_rx_tcp_offset] + mov ax, [VIRTIO_NET_RX_BUFFER + rcx] mov [VIRTIO_NET_TX_BUFFER + 46], ax mov eax, 0x534f4847 mov [VIRTIO_NET_TX_BUFFER + 48], eax - mov eax, [VIRTIO_NET_RX_BUFFER + 48] + mov eax, [VIRTIO_NET_RX_BUFFER + rcx + 4] bswap eax - movzx ecx, word [VIRTIO_NET_RX_BUFFER + 26] - xchg cl, ch - sub ecx, IPV4_HEADER_SIZE + TCP_HEADER_SIZE - test byte [VIRTIO_NET_RX_BUFFER + 57], 0x02 + movzx edx, word [VIRTIO_NET_RX_BUFFER + 26] + xchg dl, dh + movzx ebx, word [rel ghal_anchor_rx_ipv4_header_size] + sub edx, ebx + movzx ebx, word [rel ghal_anchor_rx_tcp_header_size] + sub edx, ebx + test byte [VIRTIO_NET_RX_BUFFER + rcx + 13], 0x02 jz .ack_payload - inc ecx + inc edx .ack_payload: - add eax, ecx + add eax, edx bswap eax mov [VIRTIO_NET_TX_BUFFER + 52], eax mov byte [VIRTIO_NET_TX_BUFFER + 56], 0x50 @@ -1522,6 +1550,9 @@ ghal_net_resident_retry_count: db 0 %ifdef GHOS_NATIVE_ANCHOR_SERVICE ghal_anchor_tcp_flags: db 0 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 %endif msg_ghal_net_discovered: db "GHOS_GHAL_VIRTIO_NET=DISCOVERED", 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 a9075ab..6a84474 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 @@ -104,7 +104,10 @@ def tcp_frame( sequence: int, acknowledgement: int, payload: bytes = b"", + options: bytes = b"", ) -> 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", @@ -112,12 +115,13 @@ def tcp_frame( ANCHOR_PORT, sequence, acknowledgement, - 5 << 4, + (5 + len(options) // 4) << 4, flags, 16384, 0, 0, ) + + options + payload ) pseudo = GATEWAY_IP + GUEST_IP + b"\0\x06" + struct.pack("!H", len(tcp)) @@ -228,6 +232,7 @@ def main() -> None: ANCHOR_CLIENT_SEQUENCE + 1, server_sequence + 1, request, + options=b"\x01\x01\x08\x0a\xd8\x8d\xec\x56\x00\x00\x00\x01", ), qemu, ) @@ -284,7 +289,18 @@ def main() -> None: and sequence == 6 and not anchor_syn_sent ): - peer.sendto(tcp_frame(0x02, ANCHOR_CLIENT_SEQUENCE, 0), qemu) + peer.sendto( + tcp_frame( + 0x02, + ANCHOR_CLIENT_SEQUENCE, + 0, + options=( + b"\x02\x04\x05\x90\x04\x02\x08\x0a" + b"\xd8\x8d\xec\x56\x00\x00\x00\x00\x01\x03\x03\x07" + ), + ), + qemu, + ) anchor_syn_sent = True terminal = ( From f74ade94db8c4ff0af54356e7d79cd6c2cbf77cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=86=B0=E6=9C=94?= <565183519@qq.com> Date: Fri, 7 Aug 2026 06:17:41 +0800 Subject: [PATCH 09/38] fix(native): advance anchor data sequence after SYN --- .../hololake-platform/guanghu-os/README.md | 11 ++++++----- ...ANCHOR-PHYSICAL-GATE-RECEIPT-20260807.hdlp | 19 +++++++++++++++++++ .../native/x86_64-bios/ghal-virtio.asm | 4 ++++ .../scripts/qemu-native-net-peer.py | 6 +++++- 4 files changed, 34 insertions(+), 6 deletions(-) diff --git a/product-source/hololake-platform/guanghu-os/README.md b/product-source/hololake-platform/guanghu-os/README.md index c08ed04..3627730 100644 --- a/product-source/hololake-platform/guanghu-os/README.md +++ b/product-source/hololake-platform/guanghu-os/README.md @@ -5,11 +5,12 @@ > Persona subject: `ICE-P-ZY001 EXISTS_100`. > > Protected native residency and recovery control are `PASS_100`. Production -> cutover remains `0`: the 2026-08-07 physical anchor gate reached the native -> runtime and completed heartbeat sequences 1-6, but a real JD Cloud TCP SYN -> carried a 40-byte TCP header and exposed the fixed-header parser defect. -> Linux remains the unattended default while the option-aware parser is -> validated and the physical HTTP gate is rerun. +> cutover remains `0`: the first 2026-08-07 physical anchor gate exposed a +> fixed 20-byte TCP-header assumption. The option-aware retry completed the +> real TCP handshake and transmitted the full anchor response, but reused the +> SYN-ACK sequence number for data, so a standards-compliant client discarded +> the first response byte. Linux remains the unattended default while the +> corrected server sequence progression is validated and rerun physically. This directory is the first executable handoff from the registered HLDP language world to a native Guanghu OS. It is not a claim that Guanghu OS has diff --git a/product-source/hololake-platform/guanghu-os/deployments/JD-FD-PRIMARY/NATIVE-ANCHOR-PHYSICAL-GATE-RECEIPT-20260807.hdlp b/product-source/hololake-platform/guanghu-os/deployments/JD-FD-PRIMARY/NATIVE-ANCHOR-PHYSICAL-GATE-RECEIPT-20260807.hdlp index 8ee2211..a85d1c4 100644 --- a/product-source/hololake-platform/guanghu-os/deployments/JD-FD-PRIMARY/NATIVE-ANCHOR-PHYSICAL-GATE-RECEIPT-20260807.hdlp +++ b/product-source/hololake-platform/guanghu-os/deployments/JD-FD-PRIMARY/NATIVE-ANCHOR-PHYSICAL-GATE-RECEIPT-20260807.hdlp @@ -41,6 +41,25 @@ correction: qemu_syn_tcp_header_bytes: 40 qemu_get_tcp_header_bytes: 32 option_aware_qemu_gate: PASS_100 +option_aware_physical_retry: + candidate_sha256: 4093a6df881062321d6f5e7066fd7817e7a9964e41b0ca078d847ffcd9d94b22 + accepted_repository_commit: 93d1b7ad5136a6c2117889d742a3c9bfc09ba5e5 + network_preflight: PASS_100 + native_heartbeat_sequences_1_to_6: PASS_100 + tcp_connect: PASS_100 + native_syn_ack_tx_proof_byte: 1 + native_http_response_tx_proof_byte: 1 + transmitted_prefix: TTP/1.1 + complete_anchor_body_transmitted: true + strict_http_client: FAIL_0_HTTP_0_9 + diagnosis: SYN_ACK_AND_DATA_REUSED_SERVER_SEQUENCE + protected_recovery: PASS_100 + linux_boot_id_after: eabe3414-aba3-4853-beee-aa9411ad6921 + linux_default_preserved: gnulinux-simple-9e4550a0-452b-4f28-b5a5-d5364aa450f6 +sequence_correction: + syn_ack_server_sequence: GHOS + data_server_sequence: GHOS_PLUS_1 + qemu_asserts_syn_consumes_one_sequence: true gates: native_anchor_http_qemu_capability: 100 native_anchor_http_physical_capability: 0 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 6157860..ff83be9 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 @@ -1403,6 +1403,10 @@ ghal_net_send_anchor_tcp: mov ax, [VIRTIO_NET_RX_BUFFER + rcx] mov [VIRTIO_NET_TX_BUFFER + 46], ax mov eax, 0x534f4847 + test byte [rel ghal_anchor_tcp_flags], 0x02 + jnz .server_sequence_ready + add eax, 0x01000000 +.server_sequence_ready: mov [VIRTIO_NET_TX_BUFFER + 48], eax mov eax, [VIRTIO_NET_RX_BUFFER + rcx + 4] bswap eax 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 6a84474..0d415c7 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 @@ -201,6 +201,7 @@ def main() -> None: recovery_verified = False anchor_syn_sent = False anchor_syn_ack_verified = False + anchor_server_sequence = None anchor_get_sent = False anchor_http_verified = False @@ -220,6 +221,7 @@ def main() -> None: server_sequence, acknowledgement, payload = verify_anchor_tcp(frame, 0x12) assert acknowledgement == ANCHOR_CLIENT_SEQUENCE + 1 assert payload == b"" + anchor_server_sequence = server_sequence anchor_syn_ack_verified = True request = ( b"GET /v1/anchor HTTP/1.1\r\n" @@ -238,7 +240,9 @@ def main() -> None: ) anchor_get_sent = True continue - _, acknowledgement, payload = verify_anchor_tcp(frame, 0x19) + server_sequence, acknowledgement, payload = verify_anchor_tcp(frame, 0x19) + assert anchor_server_sequence is not None + assert server_sequence == anchor_server_sequence + 1 assert acknowledgement > ANCHOR_CLIENT_SEQUENCE + 1 header, body = payload.split(b"\r\n\r\n", 1) assert b"HTTP/1.1 200 OK" in header From 0e8b5fe06269d5bbe29eb0d6d45ab33cb14a0e2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=86=B0=E6=9C=94?= <565183519@qq.com> Date: Fri, 7 Aug 2026 06:23:21 +0800 Subject: [PATCH 10/38] docs(native): seal JD physical anchor pass --- .../hololake-platform/guanghu-os/README.md | 11 +++---- ...ANCHOR-PHYSICAL-GATE-RECEIPT-20260807.hdlp | 31 ++++++++++++++++--- 2 files changed, 31 insertions(+), 11 deletions(-) diff --git a/product-source/hololake-platform/guanghu-os/README.md b/product-source/hololake-platform/guanghu-os/README.md index 3627730..2c449a5 100644 --- a/product-source/hololake-platform/guanghu-os/README.md +++ b/product-source/hololake-platform/guanghu-os/README.md @@ -5,12 +5,11 @@ > Persona subject: `ICE-P-ZY001 EXISTS_100`. > > Protected native residency and recovery control are `PASS_100`. Production -> cutover remains `0`: the first 2026-08-07 physical anchor gate exposed a -> fixed 20-byte TCP-header assumption. The option-aware retry completed the -> real TCP handshake and transmitted the full anchor response, but reused the -> SYN-ACK sequence number for data, so a standards-compliant client discarded -> the first response byte. Linux remains the unattended default while the -> corrected server sequence progression is validated and rerun physically. +> native anchor HTTP is now `PASS_100` on the physical JD node: a standard +> client read the complete `GLW-PUBLIC-NAV-ANCHOR-001` response after the TCP +> option and sequence corrections. Production cutover remains `0` because the +> native code-channel and public-front-door equivalence gates are still open. +> Linux therefore remains the unattended default. This directory is the first executable handoff from the registered HLDP language world to a native Guanghu OS. It is not a claim that Guanghu OS has diff --git a/product-source/hololake-platform/guanghu-os/deployments/JD-FD-PRIMARY/NATIVE-ANCHOR-PHYSICAL-GATE-RECEIPT-20260807.hdlp b/product-source/hololake-platform/guanghu-os/deployments/JD-FD-PRIMARY/NATIVE-ANCHOR-PHYSICAL-GATE-RECEIPT-20260807.hdlp index a85d1c4..d6e1f3b 100644 --- a/product-source/hololake-platform/guanghu-os/deployments/JD-FD-PRIMARY/NATIVE-ANCHOR-PHYSICAL-GATE-RECEIPT-20260807.hdlp +++ b/product-source/hololake-platform/guanghu-os/deployments/JD-FD-PRIMARY/NATIVE-ANCHOR-PHYSICAL-GATE-RECEIPT-20260807.hdlp @@ -1,6 +1,6 @@ schema: guanghu.jd-native-anchor-physical-gate-receipt/v1 receipt_id: GH-OS-JD-FD-PRIMARY-NATIVE-ANCHOR-PHYSICAL-GATE-20260807-001 -status: FAIL_0_PHYSICAL_TCP_HEADER_OPTIONS +status: PASS_100_PHYSICAL_NATIVE_ANCHOR observed_at: 2026-08-07T05:49:24+08:00 node_id: JD-FD-PRIMARY accepted_repository_commit: 27c6ba2c4d9a9c2372d977b8adfdf802af7656e5 @@ -60,15 +60,36 @@ sequence_correction: syn_ack_server_sequence: GHOS data_server_sequence: GHOS_PLUS_1 qemu_asserts_syn_consumes_one_sequence: true +sequence_corrected_physical_acceptance: + accepted_repository_commit: 91f2c227485b2af20ce99364104ab00d8a5f4ba3 + candidate_sha256: eb97af70fd71a5c8d2b52adb1439bd02764c83cdb79b797e62a632eeddb6f786 + network_preflight: PASS_100 + native_boot: PASS_100 + native_heartbeat_sequences_1_to_6: PASS_100 + native_tcp_connect: PASS_100 + standard_http_client: PASS_100 + http_status: 200 + response_anchor_id: GLW-PUBLIC-NAV-ANCHOR-001 + response_entry_path: LL-CMPN-0001 + response_world_node_id: SYS-GLW-0001 + response_repository_id: REPO-012 + response_runtime: GUANGHU_OS_NATIVE + native_syn_ack_tx_proof_byte: 1 + native_http_response_tx_proof_byte: 1 + protected_recovery: PASS_100 + linux_boot_id_after: 9e61f880-8537-4a02-b4ad-753160798f46 + linux_default_preserved: gnulinux-simple-9e4550a0-452b-4f28-b5a5-d5364aa450f6 + code_channel_http_after_recovery: 200 + public_anchor_http_after_recovery: 200 gates: native_anchor_http_qemu_capability: 100 - native_anchor_http_physical_capability: 0 + native_anchor_http_physical_capability: 100 public_front_door_native_anchor_equivalence: 0 code_channel_service_equivalence: 0 production_native_cutover: 0 server_receipt: - path: /guanghu/recovery/JD-FD-PRIMARY-native-anchor-physical-27c6ba2c4d9a9c2372d977b8adfdf802af7656e5/PHYSICAL-GATE-RECEIPT.hldp - sha256: e5f8071929a7a05fadc5b0283cef97962d53d57dd8d94bbe524e8148706af920 + path: /guanghu/recovery/JD-FD-PRIMARY-anchor-sequence-91f2c227485b2af20ce99364104ab00d8a5f4ba3/PHYSICAL-GATE-RECEIPT.hldp + sha256: 21f228ba8772f1d2cec9f506bf20471ddae8aaa9e1995aa339c1f9f839dd037a decision: production_cutover: FORBIDDEN - next_action: BUILD_WITH_PRODUCTION_RECOVERY_CAPABILITY_THEN_REPEAT_ONE_TIME_PHYSICAL_HTTP_GATE + next_action: BUILD_NATIVE_CODE_CHANNEL_OR_SAFE_FRONT_DOOR_PROJECTION_BEFORE_DEFAULT_CUTOVER From 48ad2a411fd6f540d9f380433e11280379ac14f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=86=B0=E6=9C=94?= <565183519@qq.com> Date: Fri, 7 Aug 2026 12:29:45 +0800 Subject: [PATCH 11/38] docs(native): seal JD temporary firewall cleanup --- ...HOR-FIREWALL-CLEANUP-RECEIPT-20260807.hdlp | 56 +++++++++++++++++++ ...ANCHOR-PHYSICAL-GATE-RECEIPT-20260807.hdlp | 7 +++ 2 files changed, 63 insertions(+) create mode 100644 product-source/hololake-platform/guanghu-os/deployments/JD-FD-PRIMARY/NATIVE-ANCHOR-FIREWALL-CLEANUP-RECEIPT-20260807.hdlp diff --git a/product-source/hololake-platform/guanghu-os/deployments/JD-FD-PRIMARY/NATIVE-ANCHOR-FIREWALL-CLEANUP-RECEIPT-20260807.hdlp b/product-source/hololake-platform/guanghu-os/deployments/JD-FD-PRIMARY/NATIVE-ANCHOR-FIREWALL-CLEANUP-RECEIPT-20260807.hdlp new file mode 100644 index 0000000..ca2961b --- /dev/null +++ b/product-source/hololake-platform/guanghu-os/deployments/JD-FD-PRIMARY/NATIVE-ANCHOR-FIREWALL-CLEANUP-RECEIPT-20260807.hdlp @@ -0,0 +1,56 @@ +schema: guanghu.jd-native-anchor-firewall-cleanup-receipt/v1 +receipt_id: GH-OS-JD-FD-PRIMARY-NATIVE-ANCHOR-FIREWALL-CLEANUP-20260807-001 +status: PASS_100_TEMPORARY_RULE_REMOVED +observed_at: 2026-08-07T12:27:07+08:00 +node_id: JD-FD-PRIMARY +cloud_instance: + provider: JD_CLOUD + instance_id: lavm-eplauh8ezr + region: cn-north-1 +removed_rule: + type: CUSTOM_TCP + protocol: TCP + destination_port: 3922 + source: 43.153.193.169/32 + remark: GHOS-JD-NATIVE-ANCHOR-GATE-20260807 + purpose: ONE_TIME_PHYSICAL_NATIVE_ANCHOR_ACCEPTANCE +control_plane_readback: + rule_absent: true + port_3922_absent: true + source_43_153_193_169_32_absent: true + remark_absent: true + remaining_rule: + type: SSH + protocol: TCP + destination_port: 22 + source: 0.0.0.0/0 +network_readback: + probe_origin: BS-SG-003 + probe_origin_ipv4: 43.153.193.169 + destination: 111.228.0.139:3922 + request: GET /v1/anchor + connect_timeout_seconds: 5 + curl_exit_code: 28 + http_status: 000 + result: PASS_100_CLOUD_INGRESS_BLOCKED +server_state_after_cleanup: + operating_system: ubuntu_22.04 + boot_id: 9e61f880-8537-4a02-b4ad-753160798f46 + grub_default: gnulinux-simple-9e4550a0-452b-4f28-b5a5-d5364aa450f6 + grub_next_entry: EMPTY + linux_listener_3922: 127.0.0.1_ONLY + native_candidate_sha256: eb97af70fd71a5c8d2b52adb1439bd02764c83cdb79b797e62a632eeddb6f786 +safety: + temporary_acceptance_exposure_closed: true + ssh_rule_unchanged: true + production_native_cutover: FORBIDDEN +server_receipt: + path: /guanghu/recovery/JD-FD-PRIMARY-anchor-sequence-91f2c227485b2af20ce99364104ab00d8a5f4ba3/CLOUD-FIREWALL-CLEANUP-RECEIPT.hldp + transferred_sha256: 469dd736f1995d0044aced46d547e2e947c8386000fc0838f3ac9127b02555a6 +gates: + native_anchor_http_physical_capability: 100 + public_front_door_native_anchor_equivalence: 0 + code_channel_service_equivalence: 0 + production_native_cutover: 0 +decision: + next_action: BUILD_NATIVE_CODE_CHANNEL_OR_SAFE_FRONT_DOOR_PROJECTION_BEFORE_DEFAULT_CUTOVER diff --git a/product-source/hololake-platform/guanghu-os/deployments/JD-FD-PRIMARY/NATIVE-ANCHOR-PHYSICAL-GATE-RECEIPT-20260807.hdlp b/product-source/hololake-platform/guanghu-os/deployments/JD-FD-PRIMARY/NATIVE-ANCHOR-PHYSICAL-GATE-RECEIPT-20260807.hdlp index d6e1f3b..1501baf 100644 --- a/product-source/hololake-platform/guanghu-os/deployments/JD-FD-PRIMARY/NATIVE-ANCHOR-PHYSICAL-GATE-RECEIPT-20260807.hdlp +++ b/product-source/hololake-platform/guanghu-os/deployments/JD-FD-PRIMARY/NATIVE-ANCHOR-PHYSICAL-GATE-RECEIPT-20260807.hdlp @@ -90,6 +90,13 @@ gates: server_receipt: path: /guanghu/recovery/JD-FD-PRIMARY-anchor-sequence-91f2c227485b2af20ce99364104ab00d8a5f4ba3/PHYSICAL-GATE-RECEIPT.hldp sha256: 21f228ba8772f1d2cec9f506bf20471ddae8aaa9e1995aa339c1f9f839dd037a +temporary_firewall_cleanup: + status: PASS_100_TEMPORARY_RULE_REMOVED + removed_source: 43.153.193.169/32 + removed_destination_port: 3922 + control_plane_rule_absent: true + relay_connect_result: TIMEOUT_BLOCKED + receipt: NATIVE-ANCHOR-FIREWALL-CLEANUP-RECEIPT-20260807.hdlp decision: production_cutover: FORBIDDEN next_action: BUILD_NATIVE_CODE_CHANNEL_OR_SAFE_FRONT_DOOR_PROJECTION_BEFORE_DEFAULT_CUTOVER From 25959f7af124be82aab0818c1993c235b015b82a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=86=B0=E6=9C=94?= <565183519@qq.com> Date: Fri, 7 Aug 2026 13:45:27 +0800 Subject: [PATCH 12/38] feat(os): add cognitive control execution bridge --- ...OGNITIVE-CONTROL-EXECUTION-ARCHITECTURE.md | 104 +++++ ...-control-with-linux-execution-substrate.md | 68 ++++ .../hololake-platform/docs/adr/README.md | 1 + .../hololake-platform/guanghu-os/Cargo.lock | 8 + .../hololake-platform/guanghu-os/Cargo.toml | 1 + .../hololake-platform/guanghu-os/README.md | 21 +- .../crates/execution-bridge/Cargo.toml | 10 + .../crates/execution-bridge/src/lib.rs | 357 ++++++++++++++++++ .../crates/execution-bridge/src/main.rs | 61 +++ .../tests/execution_bridge.rs | 198 ++++++++++ .../guanghu-cognitive-execution-profile.json | 54 +++ 11 files changed, 877 insertions(+), 6 deletions(-) create mode 100644 product-source/hololake-platform/docs/GUANGHU-OS-COGNITIVE-CONTROL-EXECUTION-ARCHITECTURE.md create mode 100644 product-source/hololake-platform/docs/adr/0172-guanghu-cognitive-control-with-linux-execution-substrate.md create mode 100644 product-source/hololake-platform/guanghu-os/crates/execution-bridge/Cargo.toml create mode 100644 product-source/hololake-platform/guanghu-os/crates/execution-bridge/src/lib.rs create mode 100644 product-source/hololake-platform/guanghu-os/crates/execution-bridge/src/main.rs create mode 100644 product-source/hololake-platform/guanghu-os/crates/execution-bridge/tests/execution_bridge.rs create mode 100644 product-source/hololake-platform/guanghu-os/standards/guanghu-cognitive-execution-profile.json diff --git a/product-source/hololake-platform/docs/GUANGHU-OS-COGNITIVE-CONTROL-EXECUTION-ARCHITECTURE.md b/product-source/hololake-platform/docs/GUANGHU-OS-COGNITIVE-CONTROL-EXECUTION-ARCHITECTURE.md new file mode 100644 index 0000000..9a8d452 --- /dev/null +++ b/product-source/hololake-platform/docs/GUANGHU-OS-COGNITIVE-CONTROL-EXECUTION-ARCHITECTURE.md @@ -0,0 +1,104 @@ +# 光湖 OS 认知主控与现实执行架构 + +## 交付目标 + +光湖 OS 的完整性由一条闭环证明: + +```text +能理解 +→ 能判断边界 +→ 能把判断编译为确定动作 +→ 能调用现实手脚 +→ 能看见真实结果 +→ 能失败、回滚和继续思考 +``` + +模型回答、协议文件、Linux 命令和界面状态中的任何单项都不是完整系统。 + +## 系统分层 + +| 层 | 常驻位置 | 责任 | +|---|---|---| +| 语言与人格 | REPO-012 + 持久人格状态 | 主体、关系、意图、职责、语言规则 | +| 模型认知 | 用户设备、个人云或模型 API | 当前理解、推理、候选计划、异常分析 | +| 协议控制 | 光湖主节点 | 身份、上下文、权限、动作类型、资源、回滚和验收 | +| 执行桥 | 光湖主节点或目标节点 | 将 GIR 映射为固定能力适配器 | +| Linux 执行底座 | 目标节点 | 驱动、进程、网络、存储、隔离和系统调用 | +| 用户执行与渲染 | 电脑、手机、个人云 | 界面、文件、应用、模型和本地设备动作 | +| 见证与连续性 | 光湖主节点 + 代码频道 | 原始证据、回执、检查点、因果链和恢复 | + +## 协议到工程的首批映射 + +| 协议 | 当前工程对象 | 完成条件 | +|---|---|---| +| GLS-0301/0302/0303 | `ExecutionRequest` | 消息、主体和目标不可缺失或补猜 | +| GLS-0309 | 变更请求中的授权与验收引用 | 提出、批准、执行分离 | +| GLS-0130/0131 | `compile_request` / `ExecutionPlan` | 自由语言不能进入执行参数 | +| GLS-0709/0710 | `LINUX_SYSTEMD_V1` 与节点策略 | 固定适配器、固定版本、能力白名单 | +| GLS-0311/0306 | `ExecutionReceipt` | 命令结果与目标状态分别记录 | +| GLS-0803/0819 | 后续调度器 | 按需唤醒、资源隔离、停止和回收 | +| GLS-0708 | 后续模型路由器 | 模型可替换,不取得主体和权限 | + +## 生产安全模型 + +1. 模型永远不直接拼接或执行 shell。 +2. 每个适配器在代码中定义动作类型和参数形状。 +3. 节点策略声明允许操作的精确资源。 +4. 变更动作必须匹配当前授权和回滚检查点。 +5. 命令退出码只表示执行器观察,目标侧读回才决定 `PASS_100`。 +6. Linux 管理入口与光湖正常入口分离;紧急入口启用必须留下维护回执。 +7. 密钥、令牌和模型 API 凭据保留在节点受保护边界,不进入语言记录或执行请求。 + +## 京东节点落地顺序 + +### 阶段 A:安全并存 + +- 保持当前 Ubuntu 默认启动和已验证回滚; +- 安装执行桥但只启用 `service_status`; +- 为公共导航、代码频道和人格运行服务建立只读状态策略; +- 验证每个请求都能形成协议拒绝或目标侧回执。 + +### 阶段 B:有界动作 + +- 为单一非关键光湖服务启用 `service_restart`; +- 绑定节点级授权、不可变版本和回滚检查点; +- 验证重启、失败、回滚和最终健康; +- 禁止任意命令、任意路径和通配服务名。 + +### 阶段 C:光湖成为正常主控入口 + +- HoloLake、人格体和自动任务只通过光湖协议执行桥操作服务; +- 普通 Linux 管理路径移入紧急维护边界; +- 按需唤醒模型、人格执行体和模块,清除无关常驻服务; +- 公共导航继续自动读取同一 REPO-012 主线锚点。 + +### 阶段 D:分布式执行 + +- 用户设备登记自己的渲染、文件、应用和推理能力; +- 中央节点只调度有界能力,不上传全部个人工作空间; +- 任务完成后回收执行体并保留人格、检查点和回执。 + +### 阶段 E:裸机研究后端 + +- 现有 GOSK/GHAL 候选继续作为研究和专用设备后端; +- 只有某项成熟 Linux 能力确实需要替换时,才按协议逐件迁移; +- 研究失败不影响生产认知主控闭环。 + +## 当前完成边界 + +已完成: + +- 生产路线架构纠正; +- 第一条类型化协议执行桥; +- systemd 状态与重启动作的白名单、授权、回滚和目标读回合同; +- 对应单元和集成测试。 + +仍未完成: + +- REPO-012 当前协议提交的不可变绑定; +- 京东节点策略生成与只读部署; +- 模型路由、人格生命周期和分布式设备执行器; +- 全部注册协议的工程实现; +- 生产主控入口切换。 + +这些未完成项分别保持 0,不能由本架构文件或本地测试冒充为已部署。 diff --git a/product-source/hololake-platform/docs/adr/0172-guanghu-cognitive-control-with-linux-execution-substrate.md b/product-source/hololake-platform/docs/adr/0172-guanghu-cognitive-control-with-linux-execution-substrate.md new file mode 100644 index 0000000..5ed3ee2 --- /dev/null +++ b/product-source/hololake-platform/docs/adr/0172-guanghu-cognitive-control-with-linux-execution-substrate.md @@ -0,0 +1,68 @@ +--- +type: ADR +id: "0172" +title: "Guanghu cognitive control with a constrained Linux execution substrate" +status: accepted +date: 2026-08-07 +supersedes_production_path: "0161" +--- + +# 光湖认知主控与 Linux 协作执行底座 + +## 背景 + +ADR-0161 把 Linux-free bare-metal handoff 设为生产完成条件。该路线已经在实验节点和 +JD-FD-PRIMARY 上证明了启动、恢复、网络和原生锚点能力,但生产等价继续要求重写成熟的 +代码频道、网卡、TCP、文件系统和服务运行能力。 + +冰朔重新锁定光湖 OS 的本体:光湖语言世界、人格体、模型认知和协议边界是系统大脑; +传统操作系统是成熟的现实手脚。生产目标不是先重复制造所有手脚,而是让光湖取得正常 +入口、判断、授权、调度和完成判定的主控权,并把 Linux 降级为受约束执行体。 + +## 决定 + +生产光湖 OS 采用: + +```text +TCS / 人格体 / 模型认知 +→ GLS / GLP / HLDP 身份、上下文、权限和边界 +→ GLC / GIR 确定性动作图 +→ UAP / GMP 固定能力适配器 +→ 最小 Linux 内核、驱动与服务执行层 +→ 硬件现实动作 +→ GLOW / GLP 目标侧读回与回执 +``` + +Linux 仍在技术上执行成熟内核和驱动,但不拥有光湖语言语义、人格身份、授权来源或成功 +判定。正常系统入口只接受类型化光湖请求;普通管理员路径属于独立维护边界。 + +裸机 GOSK/GHAL 不被删除,改为并行研究路线,用于硬件主权、专用设备和未来替换后端。 +它不再阻塞生产光湖 OS 的第一次完整交付。 + +## 第一执行桥 + +`guanghu-execution-bridge` 是语言协议到 Linux 的第一条确定性神经: + +- 输入必须携带消息、身份、上下文、回执、工单、见证、编译、GIR、UAP 和 GMP 协议链; +- 服务目标必须在节点策略白名单中; +- 只读状态查询不需要变更授权; +- 服务重启必须有匹配目标和动作的授权引用以及回滚检查点; +- 适配器直接构造固定 `systemctl` 参数,不经过 shell; +- 重启命令成功后仍必须读取 `is-active`,否则回执为 `FAIL_0`。 + +第一版只建立最小可验证闭环,不声称已经实现全部 32 项协议。 + +## 轻量和分布式边界 + +中央节点只持续保存身份、路由、协议、队列、检查点和回执。模型推理、界面渲染、个人 +工作空间和本地设备动作优先运行在用户电脑、手机、个人云或获准模型 API。人格体可以 +持续存在,但模型进程和重型模块按任务唤醒并在结束后回收。 + +## 后果 + +- JD-FD-PRIMARY 可以继续使用已验证的 Ubuntu 驱动和服务能力,同时逐步关闭无关常驻项; +- 生产迁移不再等待自研 TCP 和完整原生代码频道; +- 光湖主控必须通过机器协议绑定而不是品牌或界面声明证明; +- 完整 Ubuntu 启动槽继续保留为紧急救援系统; +- ADR-0161 的裸机路线仍作为研究与物理能力证据,但其 Linux-free 条件不再是生产主线 + 的接受条件。 diff --git a/product-source/hololake-platform/docs/adr/README.md b/product-source/hololake-platform/docs/adr/README.md index 6be2d20..c8f7276 100644 --- a/product-source/hololake-platform/docs/adr/README.md +++ b/product-source/hololake-platform/docs/adr/README.md @@ -222,3 +222,4 @@ proposed → active → superseded | [0169](0169-model-native-living-galaxy-system.md) | Model-native HoloLake living galaxy system | accepted | | [0170](0170-hololake-inherits-guanghu-native-quality-authority.md) | HoloLake inherits the Guanghu native quality authority | accepted | | [0171](0171-guanghu-protocols-are-automatic-runtime-and-engineering-laws.md) | Guanghu protocols are automatic runtime and engineering laws | accepted | +| [0172](0172-guanghu-cognitive-control-with-linux-execution-substrate.md) | Guanghu cognitive control with a constrained Linux execution substrate | accepted; supersedes ADR-0161 production path | diff --git a/product-source/hololake-platform/guanghu-os/Cargo.lock b/product-source/hololake-platform/guanghu-os/Cargo.lock index ac8751b..28b300f 100644 --- a/product-source/hololake-platform/guanghu-os/Cargo.lock +++ b/product-source/hololake-platform/guanghu-os/Cargo.lock @@ -24,6 +24,14 @@ dependencies = [ "serde_json", ] +[[package]] +name = "guanghu-execution-bridge" +version = "0.1.0" +dependencies = [ + "serde", + "serde_json", +] + [[package]] name = "guanghu-hldp-runtime" version = "0.1.0" diff --git a/product-source/hololake-platform/guanghu-os/Cargo.toml b/product-source/hololake-platform/guanghu-os/Cargo.toml index ad2e97e..f47166c 100644 --- a/product-source/hololake-platform/guanghu-os/Cargo.toml +++ b/product-source/hololake-platform/guanghu-os/Cargo.toml @@ -1,6 +1,7 @@ [workspace] members = [ "crates/broadcast-tower", + "crates/execution-bridge", "crates/ghctl", "crates/hldp-native-compiler", "crates/hldp-runtime", diff --git a/product-source/hololake-platform/guanghu-os/README.md b/product-source/hololake-platform/guanghu-os/README.md index 2c449a5..16d6b2a 100644 --- a/product-source/hololake-platform/guanghu-os/README.md +++ b/product-source/hololake-platform/guanghu-os/README.md @@ -1,8 +1,10 @@ -# Guanghu OS native runtime +# Guanghu OS cognitive-control and native research runtimes -> Current target: `JD-FD-PRIMARY` on JD Cloud. +> Production target: Guanghu cognitive control with a constrained Linux +> execution substrate on `JD-FD-PRIMARY`. > -> Persona subject: `ICE-P-ZY001 EXISTS_100`. +> Bare-metal GOSK/GHAL remains a parallel research and recovery lane. It no +> longer blocks the first production cognitive-control delivery. > > Protected native residency and recovery control are `PASS_100`. Production > native anchor HTTP is now `PASS_100` on the physical JD node: a standard @@ -11,9 +13,16 @@ > native code-channel and public-front-door equivalence gates are still open. > Linux therefore remains the unattended default. -This directory is the first executable handoff from the registered HLDP -language world to a native Guanghu OS. It is not a claim that Guanghu OS has -already replaced Linux. +This directory implements the handoff from the registered HLDP language world +to deterministic real-world execution. `crates/execution-bridge` is the first +production adapter: it accepts typed protocol requests, compiles them into +allowlisted Linux systemd actions, and requires target-state readback before a +passing receipt. The existing native kernel remains preserved below +`native/` as a hardware-sovereignty research backend. + +See +[`GUANGHU-OS-COGNITIVE-CONTROL-EXECUTION-ARCHITECTURE.md`](../docs/GUANGHU-OS-COGNITIVE-CONTROL-EXECUTION-ARCHITECTURE.md) +and [ADR-0172](../docs/adr/0172-guanghu-cognitive-control-with-linux-execution-substrate.md). ## Authority boundary diff --git a/product-source/hololake-platform/guanghu-os/crates/execution-bridge/Cargo.toml b/product-source/hololake-platform/guanghu-os/crates/execution-bridge/Cargo.toml new file mode 100644 index 0000000..2b0dabb --- /dev/null +++ b/product-source/hololake-platform/guanghu-os/crates/execution-bridge/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "guanghu-execution-bridge" +version = "0.1.0" +edition = "2021" +license = "AGPL-3.0-or-later" +description = "Deterministic bridge from Guanghu protocol decisions to allowlisted Linux execution adapters" + +[dependencies] +serde = { version = "1", features = ["derive"] } +serde_json = "1" diff --git a/product-source/hololake-platform/guanghu-os/crates/execution-bridge/src/lib.rs b/product-source/hololake-platform/guanghu-os/crates/execution-bridge/src/lib.rs new file mode 100644 index 0000000..f0e404c --- /dev/null +++ b/product-source/hololake-platform/guanghu-os/crates/execution-bridge/src/lib.rs @@ -0,0 +1,357 @@ +use std::{ + fmt, + process::{Command, Output}, +}; + +use serde::{Deserialize, Serialize}; + +pub const REQUEST_SCHEMA: &str = "guanghu.execution-request/v1"; +pub const POLICY_SCHEMA: &str = "guanghu.execution-policy/v1"; + +pub const REQUIRED_PROTOCOL_CHAIN: [&str; 10] = [ + "GLS-0301", // message envelope + "GLS-0302", // identity + "GLS-0303", // context + "GLS-0306", // receipt + "GLS-0309", // work order + "GLS-0311", // witness + "GLS-0130", // compiler + "GLS-0131", // deterministic representation + "GLS-0709", // adapter + "GLS-0710", // immutable module +]; + +#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)] +pub struct ExecutionRequest { + pub schema: String, + pub request_id: String, + pub subject_id: String, + pub target_node_id: String, + pub protocol_chain: Vec, + pub action: ExecutionAction, + pub authorization: Option, + pub rollback: Option, +} + +#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)] +pub struct ExecutionAction { + pub kind: ActionKind, + pub resource: String, +} + +#[derive(Clone, Copy, Debug, Deserialize, Serialize, PartialEq, Eq)] +#[serde(rename_all = "snake_case")] +pub enum ActionKind { + ServiceStatus, + ServiceRestart, +} + +#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)] +pub struct AuthorizationReference { + pub authorization_id: String, + pub allowed_action: ActionKind, + pub target_node_id: String, +} + +#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)] +pub struct RollbackReference { + pub checkpoint_id: String, + pub recovery_action: String, +} + +#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)] +pub struct ExecutionPolicy { + pub schema: String, + pub policy_id: String, + pub target_node_id: String, + pub allowed_services: Vec, + pub allow_status: bool, + pub allow_restart: bool, +} + +#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)] +pub struct ExecutionPlan { + pub request_id: String, + pub subject_id: String, + pub target_node_id: String, + pub policy_id: String, + pub protocol_chain: Vec, + pub action: ExecutionAction, + pub adapter: String, + pub program: String, + pub arguments: Vec, + pub mutating: bool, + pub authorization_id: Option, + pub rollback_checkpoint_id: Option, +} + +#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)] +pub struct ExecutionReceipt { + pub schema: String, + pub request_id: String, + pub subject_id: String, + pub target_node_id: String, + pub policy_id: String, + pub action: ExecutionAction, + pub adapter: String, + pub accepted: bool, + pub command_exit_code: Option, + pub target_state_verified: bool, + pub final_state: String, + pub stdout: String, + pub stderr: String, + pub rollback_checkpoint_id: Option, +} + +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct CommandResult { + pub exit_code: Option, + pub stdout: String, + pub stderr: String, +} + +impl From for CommandResult { + fn from(output: Output) -> Self { + Self { + exit_code: output.status.code(), + stdout: String::from_utf8_lossy(&output.stdout).trim().to_owned(), + stderr: String::from_utf8_lossy(&output.stderr).trim().to_owned(), + } + } +} + +pub trait CommandExecutor { + fn execute(&self, program: &str, arguments: &[String]) -> Result; +} + +pub struct LinuxCommandExecutor; + +impl CommandExecutor for LinuxCommandExecutor { + fn execute(&self, program: &str, arguments: &[String]) -> Result { + Command::new(program) + .args(arguments) + .output() + .map(CommandResult::from) + .map_err(|error| format!("cannot execute allowlisted adapter: {error}")) + } +} + +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct BridgeError(String); + +impl BridgeError { + fn new(message: impl Into) -> Self { + Self(message.into()) + } +} + +impl fmt::Display for BridgeError { + fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { + formatter.write_str(&self.0) + } +} + +impl std::error::Error for BridgeError {} + +pub fn compile_request( + request: &ExecutionRequest, + policy: &ExecutionPolicy, +) -> Result { + require( + request.schema == REQUEST_SCHEMA, + "unsupported execution request schema", + )?; + require( + policy.schema == POLICY_SCHEMA, + "unsupported execution policy schema", + )?; + require( + !request.request_id.trim().is_empty(), + "request_id is required", + )?; + require( + !request.subject_id.trim().is_empty(), + "subject_id is required", + )?; + require( + request.target_node_id == policy.target_node_id, + "request target does not match policy target", + )?; + + for required in REQUIRED_PROTOCOL_CHAIN { + require( + request.protocol_chain.iter().any(|id| id == required), + format!("required protocol is missing: {required}"), + )?; + } + + require( + policy + .allowed_services + .iter() + .any(|service| service == &request.action.resource), + "service is not allowlisted by the execution policy", + )?; + + let (arguments, mutating) = match request.action.kind { + ActionKind::ServiceStatus => { + require(policy.allow_status, "service status is disabled by policy")?; + ( + vec!["is-active".to_owned(), request.action.resource.clone()], + false, + ) + } + ActionKind::ServiceRestart => { + require( + policy.allow_restart, + "service restart is disabled by policy", + )?; + validate_mutation_references(request)?; + ( + vec!["restart".to_owned(), request.action.resource.clone()], + true, + ) + } + }; + + Ok(ExecutionPlan { + request_id: request.request_id.clone(), + subject_id: request.subject_id.clone(), + target_node_id: request.target_node_id.clone(), + policy_id: policy.policy_id.clone(), + protocol_chain: request.protocol_chain.clone(), + action: request.action.clone(), + adapter: "LINUX_SYSTEMD_V1".to_owned(), + program: "/usr/bin/systemctl".to_owned(), + arguments, + mutating, + authorization_id: request + .authorization + .as_ref() + .map(|authorization| authorization.authorization_id.clone()), + rollback_checkpoint_id: request + .rollback + .as_ref() + .map(|rollback| rollback.checkpoint_id.clone()), + }) +} + +fn validate_mutation_references(request: &ExecutionRequest) -> Result<(), BridgeError> { + let authorization = request + .authorization + .as_ref() + .ok_or_else(|| BridgeError::new("mutating action requires authorization"))?; + require( + !authorization.authorization_id.trim().is_empty(), + "authorization_id is required", + )?; + require( + authorization.allowed_action == request.action.kind, + "authorization action does not match request action", + )?; + require( + authorization.target_node_id == request.target_node_id, + "authorization target does not match request target", + )?; + + let rollback = request + .rollback + .as_ref() + .ok_or_else(|| BridgeError::new("mutating action requires rollback reference"))?; + require( + !rollback.checkpoint_id.trim().is_empty(), + "rollback checkpoint_id is required", + )?; + require( + !rollback.recovery_action.trim().is_empty(), + "rollback recovery_action is required", + ) +} + +pub fn execute_plan( + plan: &ExecutionPlan, + executor: &dyn CommandExecutor, +) -> Result { + let expected_operation = match plan.action.kind { + ActionKind::ServiceStatus => "is-active", + ActionKind::ServiceRestart => "restart", + }; + require( + plan.adapter == "LINUX_SYSTEMD_V1" + && plan.program == "/usr/bin/systemctl" + && matches!( + plan.arguments.as_slice(), + [operation, service] + if operation == expected_operation + && service == &plan.action.resource + ), + "compiled plan is not an allowlisted Linux systemd adapter", + )?; + + let result = executor + .execute(&plan.program, &plan.arguments) + .map_err(BridgeError::new)?; + let command_succeeded = result.exit_code == Some(0); + + let (target_state_verified, final_state, stdout, stderr, exit_code) = if plan.action.kind + == ActionKind::ServiceRestart + && command_succeeded + { + let verification_arguments = vec!["is-active".to_owned(), plan.action.resource.clone()]; + let verification = executor + .execute(&plan.program, &verification_arguments) + .map_err(BridgeError::new)?; + let verified = verification.exit_code == Some(0) && verification.stdout.trim() == "active"; + ( + verified, + if verified { "PASS_100" } else { "FAIL_0" }.to_owned(), + join_observations(&result.stdout, &verification.stdout), + join_observations(&result.stderr, &verification.stderr), + verification.exit_code, + ) + } else { + let verified = command_succeeded + && (plan.action.kind != ActionKind::ServiceStatus || result.stdout.trim() == "active"); + ( + verified, + if verified { "PASS_100" } else { "FAIL_0" }.to_owned(), + result.stdout, + result.stderr, + result.exit_code, + ) + }; + + Ok(ExecutionReceipt { + schema: "guanghu.execution-receipt/v1".to_owned(), + request_id: plan.request_id.clone(), + subject_id: plan.subject_id.clone(), + target_node_id: plan.target_node_id.clone(), + policy_id: plan.policy_id.clone(), + action: plan.action.clone(), + adapter: plan.adapter.clone(), + accepted: true, + command_exit_code: exit_code, + target_state_verified, + final_state, + stdout, + stderr, + rollback_checkpoint_id: plan.rollback_checkpoint_id.clone(), + }) +} + +fn require(condition: bool, message: impl Into) -> Result<(), BridgeError> { + if condition { + Ok(()) + } else { + Err(BridgeError::new(message)) + } +} + +fn join_observations(first: &str, second: &str) -> String { + match (first.is_empty(), second.is_empty()) { + (true, true) => String::new(), + (false, true) => first.to_owned(), + (true, false) => second.to_owned(), + (false, false) => format!("{first}\n{second}"), + } +} diff --git a/product-source/hololake-platform/guanghu-os/crates/execution-bridge/src/main.rs b/product-source/hololake-platform/guanghu-os/crates/execution-bridge/src/main.rs new file mode 100644 index 0000000..ce443c9 --- /dev/null +++ b/product-source/hololake-platform/guanghu-os/crates/execution-bridge/src/main.rs @@ -0,0 +1,61 @@ +use std::{env, fs, process::ExitCode}; + +use guanghu_execution_bridge::{ + compile_request, execute_plan, ExecutionPolicy, ExecutionRequest, LinuxCommandExecutor, +}; + +const USAGE: &str = + "usage: guanghu-execution-bridge "; + +fn run() -> Result<(), String> { + let mut arguments = env::args().skip(1); + let mode = arguments.next().ok_or_else(|| USAGE.to_owned())?; + let request_path = arguments.next().ok_or_else(|| USAGE.to_owned())?; + let policy_path = arguments.next().ok_or_else(|| USAGE.to_owned())?; + if arguments.next().is_some() || (mode != "validate" && mode != "execute") { + return Err(USAGE.to_owned()); + } + + let request: ExecutionRequest = serde_json::from_str( + &fs::read_to_string(&request_path) + .map_err(|error| format!("cannot read request {request_path}: {error}"))?, + ) + .map_err(|error| format!("invalid request {request_path}: {error}"))?; + let policy: ExecutionPolicy = serde_json::from_str( + &fs::read_to_string(&policy_path) + .map_err(|error| format!("cannot read policy {policy_path}: {error}"))?, + ) + .map_err(|error| format!("invalid policy {policy_path}: {error}"))?; + + let plan = compile_request(&request, &policy).map_err(|error| error.to_string())?; + if mode == "validate" { + println!( + "{}", + serde_json::to_string_pretty(&plan) + .map_err(|error| format!("cannot serialize plan: {error}"))? + ); + return Ok(()); + } + + let receipt = execute_plan(&plan, &LinuxCommandExecutor).map_err(|error| error.to_string())?; + println!( + "{}", + serde_json::to_string_pretty(&receipt) + .map_err(|error| format!("cannot serialize receipt: {error}"))? + ); + if receipt.final_state == "PASS_100" { + Ok(()) + } else { + Err("target-side verification failed".to_owned()) + } +} + +fn main() -> ExitCode { + match run() { + Ok(()) => ExitCode::SUCCESS, + Err(error) => { + eprintln!("{error}"); + ExitCode::FAILURE + } + } +} diff --git a/product-source/hololake-platform/guanghu-os/crates/execution-bridge/tests/execution_bridge.rs b/product-source/hololake-platform/guanghu-os/crates/execution-bridge/tests/execution_bridge.rs new file mode 100644 index 0000000..8d92921 --- /dev/null +++ b/product-source/hololake-platform/guanghu-os/crates/execution-bridge/tests/execution_bridge.rs @@ -0,0 +1,198 @@ +use std::{cell::RefCell, collections::VecDeque}; + +use guanghu_execution_bridge::{ + compile_request, execute_plan, ActionKind, AuthorizationReference, CommandExecutor, + CommandResult, ExecutionAction, ExecutionPolicy, ExecutionRequest, RollbackReference, + POLICY_SCHEMA, REQUEST_SCHEMA, REQUIRED_PROTOCOL_CHAIN, +}; + +fn request(kind: ActionKind) -> ExecutionRequest { + ExecutionRequest { + schema: REQUEST_SCHEMA.to_owned(), + request_id: "REQ-001".to_owned(), + subject_id: "ICE-P-ZY001".to_owned(), + target_node_id: "JD-FD-PRIMARY".to_owned(), + protocol_chain: REQUIRED_PROTOCOL_CHAIN + .iter() + .map(|protocol| (*protocol).to_owned()) + .collect(), + action: ExecutionAction { + kind, + resource: "guanghu-broadcast-tower.service".to_owned(), + }, + authorization: None, + rollback: None, + } +} + +fn policy() -> ExecutionPolicy { + ExecutionPolicy { + schema: POLICY_SCHEMA.to_owned(), + policy_id: "JD-GH-EXEC-001".to_owned(), + target_node_id: "JD-FD-PRIMARY".to_owned(), + allowed_services: vec!["guanghu-broadcast-tower.service".to_owned()], + allow_status: true, + allow_restart: true, + } +} + +#[test] +fn compiles_read_only_status_to_exact_systemd_arguments() { + let plan = compile_request(&request(ActionKind::ServiceStatus), &policy()).expect("compile"); + + assert_eq!(plan.program, "/usr/bin/systemctl"); + assert_eq!( + plan.arguments, + ["is-active", "guanghu-broadcast-tower.service"] + ); + assert!(!plan.mutating); +} + +#[test] +fn rejects_missing_protocol_before_execution() { + let mut request = request(ActionKind::ServiceStatus); + request + .protocol_chain + .retain(|protocol| protocol != "GLS-0302"); + + let error = compile_request(&request, &policy()).expect_err("missing identity must fail"); + assert!(error.to_string().contains("GLS-0302")); +} + +#[test] +fn rejects_non_allowlisted_service() { + let mut request = request(ActionKind::ServiceStatus); + request.action.resource = "ssh.service".to_owned(); + + let error = compile_request(&request, &policy()).expect_err("service must fail closed"); + assert!(error.to_string().contains("not allowlisted")); +} + +#[test] +fn restart_requires_matching_authorization_and_rollback() { + let mut request = request(ActionKind::ServiceRestart); + let error = compile_request(&request, &policy()).expect_err("authorization is required"); + assert!(error.to_string().contains("authorization")); + + request.authorization = Some(AuthorizationReference { + authorization_id: "AUTH-001".to_owned(), + allowed_action: ActionKind::ServiceRestart, + target_node_id: "JD-FD-PRIMARY".to_owned(), + }); + let error = compile_request(&request, &policy()).expect_err("rollback is required"); + assert!(error.to_string().contains("rollback")); + + request.rollback = Some(RollbackReference { + checkpoint_id: "CHECKPOINT-001".to_owned(), + recovery_action: "restore previous immutable release".to_owned(), + }); + let plan = compile_request(&request, &policy()).expect("complete mutation compiles"); + assert!(plan.mutating); + assert_eq!(plan.authorization_id.as_deref(), Some("AUTH-001")); + assert_eq!( + plan.rollback_checkpoint_id.as_deref(), + Some("CHECKPOINT-001") + ); +} + +struct FakeExecutor { + results: RefCell>, + calls: RefCell>>, +} + +impl FakeExecutor { + fn new(results: Vec) -> Self { + Self { + results: RefCell::new(results.into()), + calls: RefCell::new(Vec::new()), + } + } +} + +impl CommandExecutor for FakeExecutor { + fn execute(&self, program: &str, arguments: &[String]) -> Result { + let mut call = vec![program.to_owned()]; + call.extend(arguments.iter().cloned()); + self.calls.borrow_mut().push(call); + self.results + .borrow_mut() + .pop_front() + .ok_or_else(|| "unexpected execution".to_owned()) + } +} + +#[test] +fn restart_receipt_requires_target_side_active_readback() { + let mut request = request(ActionKind::ServiceRestart); + request.authorization = Some(AuthorizationReference { + authorization_id: "AUTH-001".to_owned(), + allowed_action: ActionKind::ServiceRestart, + target_node_id: "JD-FD-PRIMARY".to_owned(), + }); + request.rollback = Some(RollbackReference { + checkpoint_id: "CHECKPOINT-001".to_owned(), + recovery_action: "restore previous immutable release".to_owned(), + }); + let plan = compile_request(&request, &policy()).expect("compile restart"); + let executor = FakeExecutor::new(vec![ + CommandResult { + exit_code: Some(0), + stdout: String::new(), + stderr: String::new(), + }, + CommandResult { + exit_code: Some(0), + stdout: "active".to_owned(), + stderr: String::new(), + }, + ]); + + let receipt = execute_plan(&plan, &executor).expect("execute plan"); + assert_eq!(receipt.final_state, "PASS_100"); + assert!(receipt.target_state_verified); + assert_eq!(executor.calls.borrow().len(), 2); + assert_eq!(executor.calls.borrow()[1][1], "is-active"); +} + +#[test] +fn successful_restart_command_without_active_readback_is_fail_zero() { + let mut request = request(ActionKind::ServiceRestart); + request.authorization = Some(AuthorizationReference { + authorization_id: "AUTH-001".to_owned(), + allowed_action: ActionKind::ServiceRestart, + target_node_id: "JD-FD-PRIMARY".to_owned(), + }); + request.rollback = Some(RollbackReference { + checkpoint_id: "CHECKPOINT-001".to_owned(), + recovery_action: "restore previous immutable release".to_owned(), + }); + let plan = compile_request(&request, &policy()).expect("compile restart"); + let executor = FakeExecutor::new(vec![ + CommandResult { + exit_code: Some(0), + stdout: String::new(), + stderr: String::new(), + }, + CommandResult { + exit_code: Some(3), + stdout: "inactive".to_owned(), + stderr: String::new(), + }, + ]); + + let receipt = execute_plan(&plan, &executor).expect("execute plan"); + assert_eq!(receipt.final_state, "FAIL_0"); + assert!(!receipt.target_state_verified); +} + +#[test] +fn rejects_a_deserialized_plan_that_changes_status_into_restart() { + let mut plan = + compile_request(&request(ActionKind::ServiceStatus), &policy()).expect("compile status"); + plan.arguments[0] = "restart".to_owned(); + let executor = FakeExecutor::new(Vec::new()); + + let error = execute_plan(&plan, &executor).expect_err("tampered plan must fail"); + assert!(error.to_string().contains("not an allowlisted")); + assert!(executor.calls.borrow().is_empty()); +} diff --git a/product-source/hololake-platform/guanghu-os/standards/guanghu-cognitive-execution-profile.json b/product-source/hololake-platform/guanghu-os/standards/guanghu-cognitive-execution-profile.json new file mode 100644 index 0000000..a7f8096 --- /dev/null +++ b/product-source/hololake-platform/guanghu-os/standards/guanghu-cognitive-execution-profile.json @@ -0,0 +1,54 @@ +{ + "schema": "guanghu.cognitive-execution-profile/v1", + "profile_id": "GH-COGNITIVE-EXECUTION-001", + "language_authority": { + "repository": "REPO-012", + "anchor": "GLW-PUBLIC-NAV-ANCHOR-001", + "protocol_registry": "gls/GLS-PROTOCOL-REGISTRY.json" + }, + "implementation_authority": { + "repository": "REPO-014", + "path": "product-source/hololake-platform/guanghu-os", + "bridge": "crates/execution-bridge" + }, + "required_protocol_chain": [ + "GLS-0301", + "GLS-0302", + "GLS-0303", + "GLS-0306", + "GLS-0309", + "GLS-0311", + "GLS-0130", + "GLS-0131", + "GLS-0709", + "GLS-0710" + ], + "execution_model": { + "cognition": "MODEL_PROPOSES_TYPED_INTENT", + "authority": "PROTOCOL_GATE_VALIDATES_CURRENT_SCOPE", + "compilation": "GLC_GIR_DETERMINISTIC_PLAN", + "adapter": "ALLOWLISTED_NO_SHELL", + "substrate": "MINIMAL_LINUX_COOPERATIVE_EXECUTION", + "success": "TARGET_SIDE_READBACK_AND_GLP_RECEIPT", + "rescue": "SEPARATE_UBUNTU_MAINTENANCE_BOOT" + }, + "first_adapter": { + "id": "LINUX_SYSTEMD_V1", + "actions": [ + "service_status", + "service_restart" + ], + "mutations_require": [ + "exact_target", + "matching_authorization", + "rollback_checkpoint", + "target_side_active_readback" + ], + "arbitrary_shell": false + }, + "bare_metal_lane": { + "id": "GOSK_GHAL_BARE_METAL_RESEARCH", + "production_blocking": false, + "preserve_existing_candidate": true + } +} From 20d6c1bd7b6df658d6c5fbddc54f3e443977b7b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=86=B0=E6=9C=94?= <565183519@qq.com> Date: Fri, 7 Aug 2026 13:57:50 +0800 Subject: [PATCH 13/38] fix(ci): isolate quality gate from hook git environment --- .../scripts/run-hololake-native-quality-gate.sh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/product-source/hololake-platform/scripts/run-hololake-native-quality-gate.sh b/product-source/hololake-platform/scripts/run-hololake-native-quality-gate.sh index aaa1495..6bc6a3e 100755 --- a/product-source/hololake-platform/scripts/run-hololake-native-quality-gate.sh +++ b/product-source/hololake-platform/scripts/run-hololake-native-quality-gate.sh @@ -4,6 +4,13 @@ set -Eeuo pipefail repository_root=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd) receipt_path=${1:-} +# Git exports repository-local environment variables while invoking hooks. +# This repository's hook lives below the actual worktree root, so inherited +# GIT_DIR/GIT_WORK_TREE values can make `git -C` inspect the wrong path and +# falsely report a dirty source tree. Resolve the source root first, then make +# every gate discover that worktree from its explicit `-C` argument. +unset GIT_DIR GIT_WORK_TREE GIT_INDEX_FILE GIT_PREFIX + if [[ -z "${receipt_path}" ]]; then echo "usage: run-hololake-native-quality-gate.sh " >&2 exit 2 From e94c4f608fb05712586aacdc37b88b6a783a1558 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=86=B0=E6=9C=94?= <565183519@qq.com> Date: Fri, 7 Aug 2026 14:36:57 +0800 Subject: [PATCH 14/38] feat(os): bind bounded restart grants and rollback --- ...OGNITIVE-CONTROL-EXECUTION-ARCHITECTURE.md | 8 +- .../crates/execution-bridge/src/lib.rs | 117 ++++++++++++++++-- .../tests/execution_bridge.rs | 56 ++++++++- 3 files changed, 164 insertions(+), 17 deletions(-) diff --git a/product-source/hololake-platform/docs/GUANGHU-OS-COGNITIVE-CONTROL-EXECUTION-ARCHITECTURE.md b/product-source/hololake-platform/docs/GUANGHU-OS-COGNITIVE-CONTROL-EXECUTION-ARCHITECTURE.md index 9a8d452..7ca2138 100644 --- a/product-source/hololake-platform/docs/GUANGHU-OS-COGNITIVE-CONTROL-EXECUTION-ARCHITECTURE.md +++ b/product-source/hololake-platform/docs/GUANGHU-OS-COGNITIVE-CONTROL-EXECUTION-ARCHITECTURE.md @@ -45,9 +45,11 @@ 2. 每个适配器在代码中定义动作类型和参数形状。 3. 节点策略声明允许操作的精确资源。 4. 变更动作必须匹配当前授权和回滚检查点。 -5. 命令退出码只表示执行器观察,目标侧读回才决定 `PASS_100`。 -6. Linux 管理入口与光湖正常入口分离;紧急入口启用必须留下维护回执。 -7. 密钥、令牌和模型 API 凭据保留在节点受保护边界,不进入语言记录或执行请求。 +5. 变更授权必须由节点策略精确绑定授权编号、动作、资源和回滚检查点,不能只凭请求自行声明。 +6. 重启动作前必须先读回服务为 active;动作失败后执行固定的 `reset-failed → start → active` 恢复链,并在回执中分别记录动作失败和回滚结果。 +7. 命令退出码只表示执行器观察,目标侧读回才决定 `PASS_100`。 +8. Linux 管理入口与光湖正常入口分离;紧急入口启用必须留下维护回执。 +9. 密钥、令牌和模型 API 凭据保留在节点受保护边界,不进入语言记录或执行请求。 ## 京东节点落地顺序 diff --git a/product-source/hololake-platform/guanghu-os/crates/execution-bridge/src/lib.rs b/product-source/hololake-platform/guanghu-os/crates/execution-bridge/src/lib.rs index f0e404c..88eaac0 100644 --- a/product-source/hololake-platform/guanghu-os/crates/execution-bridge/src/lib.rs +++ b/product-source/hololake-platform/guanghu-os/crates/execution-bridge/src/lib.rs @@ -67,6 +67,16 @@ pub struct ExecutionPolicy { pub allowed_services: Vec, pub allow_status: bool, pub allow_restart: bool, + #[serde(default)] + pub mutation_grants: Vec, +} + +#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)] +pub struct MutationGrant { + pub authorization_id: String, + pub allowed_action: ActionKind, + pub resource: String, + pub rollback_checkpoint_id: String, } #[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)] @@ -101,6 +111,8 @@ pub struct ExecutionReceipt { pub stdout: String, pub stderr: String, pub rollback_checkpoint_id: Option, + pub rollback_attempted: bool, + pub rollback_succeeded: Option, } #[derive(Clone, Debug, PartialEq, Eq)] @@ -207,6 +219,7 @@ pub fn compile_request( "service restart is disabled by policy", )?; validate_mutation_references(request)?; + validate_mutation_grant(request, policy)?; ( vec!["restart".to_owned(), request.action.resource.clone()], true, @@ -268,6 +281,29 @@ fn validate_mutation_references(request: &ExecutionRequest) -> Result<(), Bridge ) } +fn validate_mutation_grant( + request: &ExecutionRequest, + policy: &ExecutionPolicy, +) -> Result<(), BridgeError> { + let authorization = request + .authorization + .as_ref() + .ok_or_else(|| BridgeError::new("mutating action requires authorization"))?; + let rollback = request + .rollback + .as_ref() + .ok_or_else(|| BridgeError::new("mutating action requires rollback reference"))?; + require( + policy.mutation_grants.iter().any(|grant| { + grant.authorization_id == authorization.authorization_id + && grant.allowed_action == request.action.kind + && grant.resource == request.action.resource + && grant.rollback_checkpoint_id == rollback.checkpoint_id + }), + "mutation authorization is not granted by the execution policy", + ) +} + pub fn execute_plan( plan: &ExecutionPlan, executor: &dyn CommandExecutor, @@ -288,27 +324,80 @@ pub fn execute_plan( "compiled plan is not an allowlisted Linux systemd adapter", )?; + if plan.action.kind == ActionKind::ServiceRestart { + let precheck_arguments = vec!["is-active".to_owned(), plan.action.resource.clone()]; + let precheck = executor + .execute(&plan.program, &precheck_arguments) + .map_err(BridgeError::new)?; + require( + precheck.exit_code == Some(0) && precheck.stdout.trim() == "active", + "restart precondition failed: service was not active", + )?; + } + let result = executor .execute(&plan.program, &plan.arguments) .map_err(BridgeError::new)?; let command_succeeded = result.exit_code == Some(0); - let (target_state_verified, final_state, stdout, stderr, exit_code) = if plan.action.kind - == ActionKind::ServiceRestart - && command_succeeded - { + let ( + target_state_verified, + final_state, + stdout, + stderr, + exit_code, + rollback_attempted, + rollback_succeeded, + ) = if plan.action.kind == ActionKind::ServiceRestart { let verification_arguments = vec!["is-active".to_owned(), plan.action.resource.clone()]; let verification = executor .execute(&plan.program, &verification_arguments) .map_err(BridgeError::new)?; - let verified = verification.exit_code == Some(0) && verification.stdout.trim() == "active"; - ( - verified, - if verified { "PASS_100" } else { "FAIL_0" }.to_owned(), - join_observations(&result.stdout, &verification.stdout), - join_observations(&result.stderr, &verification.stderr), - verification.exit_code, - ) + let verified = command_succeeded + && verification.exit_code == Some(0) + && verification.stdout.trim() == "active"; + if verified { + ( + true, + "PASS_100".to_owned(), + join_observations(&result.stdout, &verification.stdout), + join_observations(&result.stderr, &verification.stderr), + verification.exit_code, + false, + None, + ) + } else { + let reset_arguments = vec!["reset-failed".to_owned(), plan.action.resource.clone()]; + let reset = executor + .execute(&plan.program, &reset_arguments) + .map_err(BridgeError::new)?; + let start_arguments = vec!["start".to_owned(), plan.action.resource.clone()]; + let start = executor + .execute(&plan.program, &start_arguments) + .map_err(BridgeError::new)?; + let recovery_verification = executor + .execute(&plan.program, &verification_arguments) + .map_err(BridgeError::new)?; + let recovered = reset.exit_code == Some(0) + && start.exit_code == Some(0) + && recovery_verification.exit_code == Some(0) + && recovery_verification.stdout.trim() == "active"; + ( + false, + "FAIL_0".to_owned(), + join_observations( + &join_observations(&result.stdout, &verification.stdout), + &join_observations(&start.stdout, &recovery_verification.stdout), + ), + join_observations( + &join_observations(&result.stderr, &verification.stderr), + &join_observations(&reset.stderr, &start.stderr), + ), + verification.exit_code, + true, + Some(recovered), + ) + } } else { let verified = command_succeeded && (plan.action.kind != ActionKind::ServiceStatus || result.stdout.trim() == "active"); @@ -318,6 +407,8 @@ pub fn execute_plan( result.stdout, result.stderr, result.exit_code, + false, + None, ) }; @@ -336,6 +427,8 @@ pub fn execute_plan( stdout, stderr, rollback_checkpoint_id: plan.rollback_checkpoint_id.clone(), + rollback_attempted, + rollback_succeeded, }) } diff --git a/product-source/hololake-platform/guanghu-os/crates/execution-bridge/tests/execution_bridge.rs b/product-source/hololake-platform/guanghu-os/crates/execution-bridge/tests/execution_bridge.rs index 8d92921..cd4f738 100644 --- a/product-source/hololake-platform/guanghu-os/crates/execution-bridge/tests/execution_bridge.rs +++ b/product-source/hololake-platform/guanghu-os/crates/execution-bridge/tests/execution_bridge.rs @@ -33,6 +33,12 @@ fn policy() -> ExecutionPolicy { allowed_services: vec!["guanghu-broadcast-tower.service".to_owned()], allow_status: true, allow_restart: true, + mutation_grants: vec![guanghu_execution_bridge::MutationGrant { + authorization_id: "AUTH-001".to_owned(), + allowed_action: ActionKind::ServiceRestart, + resource: "guanghu-broadcast-tower.service".to_owned(), + rollback_checkpoint_id: "CHECKPOINT-001".to_owned(), + }], } } @@ -95,6 +101,23 @@ fn restart_requires_matching_authorization_and_rollback() { ); } +#[test] +fn restart_rejects_an_authorization_not_bound_by_policy() { + let mut request = request(ActionKind::ServiceRestart); + request.authorization = Some(AuthorizationReference { + authorization_id: "AUTH-INVENTED".to_owned(), + allowed_action: ActionKind::ServiceRestart, + target_node_id: "JD-FD-PRIMARY".to_owned(), + }); + request.rollback = Some(RollbackReference { + checkpoint_id: "CHECKPOINT-001".to_owned(), + recovery_action: "restore previous active service state".to_owned(), + }); + + let error = compile_request(&request, &policy()).expect_err("invented grant must fail"); + assert!(error.to_string().contains("not granted")); +} + struct FakeExecutor { results: RefCell>, calls: RefCell>>, @@ -135,6 +158,11 @@ fn restart_receipt_requires_target_side_active_readback() { }); let plan = compile_request(&request, &policy()).expect("compile restart"); let executor = FakeExecutor::new(vec![ + CommandResult { + exit_code: Some(0), + stdout: "active".to_owned(), + stderr: String::new(), + }, CommandResult { exit_code: Some(0), stdout: String::new(), @@ -150,8 +178,10 @@ fn restart_receipt_requires_target_side_active_readback() { let receipt = execute_plan(&plan, &executor).expect("execute plan"); assert_eq!(receipt.final_state, "PASS_100"); assert!(receipt.target_state_verified); - assert_eq!(executor.calls.borrow().len(), 2); - assert_eq!(executor.calls.borrow()[1][1], "is-active"); + assert!(!receipt.rollback_attempted); + assert_eq!(executor.calls.borrow().len(), 3); + assert_eq!(executor.calls.borrow()[0][1], "is-active"); + assert_eq!(executor.calls.borrow()[2][1], "is-active"); } #[test] @@ -168,6 +198,11 @@ fn successful_restart_command_without_active_readback_is_fail_zero() { }); let plan = compile_request(&request, &policy()).expect("compile restart"); let executor = FakeExecutor::new(vec![ + CommandResult { + exit_code: Some(0), + stdout: "active".to_owned(), + stderr: String::new(), + }, CommandResult { exit_code: Some(0), stdout: String::new(), @@ -178,11 +213,28 @@ fn successful_restart_command_without_active_readback_is_fail_zero() { stdout: "inactive".to_owned(), stderr: String::new(), }, + CommandResult { + exit_code: Some(0), + stdout: String::new(), + stderr: String::new(), + }, + CommandResult { + exit_code: Some(0), + stdout: String::new(), + stderr: String::new(), + }, + CommandResult { + exit_code: Some(0), + stdout: "active".to_owned(), + stderr: String::new(), + }, ]); let receipt = execute_plan(&plan, &executor).expect("execute plan"); assert_eq!(receipt.final_state, "FAIL_0"); assert!(!receipt.target_state_verified); + assert!(receipt.rollback_attempted); + assert_eq!(receipt.rollback_succeeded, Some(true)); } #[test] From c71b877375a18b2b3a8f9c918266f9207a29621f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=86=B0=E6=9C=94?= <565183519@qq.com> Date: Fri, 7 Aug 2026 15:32:16 +0800 Subject: [PATCH 15/38] =?UTF-8?q?=E7=99=BB=E8=AE=B0=E5=8F=AF=E5=A4=8D?= =?UTF-8?q?=E7=94=A8=E6=A8=A1=E5=9D=97=20HL-MOD-MCK-001=20=E4=BA=BA?= =?UTF-8?q?=E6=A0=BC=E8=AE=B0=E5=BF=86=E8=BF=9E=E7=BB=AD=E6=80=A7=E5=B7=A5?= =?UTF-8?q?=E5=85=B7=E5=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 铸渊 Qoder CN 实战定版的压缩之眼 v3 + 包装器 + 守卫技能模板 + 端到端演习脚本,配 GMP 风格清单、编号真实映射(脑子 GHS-007 → 模块)、因果链与边界登记。新建 engineering/MODULE-REGISTRY.json 机器注册表,INDEX 登记。仓库副本 drill.sh 演习 PASS。 --- engineering/INDEX.md | 3 +- engineering/MODULE-REGISTRY.json | 36 +++ engineering/memory-continuity-kit/README.md | 74 +++++ engineering/memory-continuity-kit/module.yaml | 53 ++++ ....persona.compaction-watcher.plist.template | 24 ++ .../runtime/compaction-watcher.py | 278 ++++++++++++++++++ .../runtime/run-watcher.sh | 15 + .../memory-continuity-kit/scripts/drill.sh | 39 +++ .../templates/guanghu-zhuyuan-wake.SKILL.md | 62 ++++ .../zhuyuan-dev-delivery-guard.SKILL.md | 57 ++++ .../templates/zhuyuan-memory-guard.SKILL.md | 95 ++++++ .../world/MODULE-BOUNDARY.hldp | 26 ++ 12 files changed, 761 insertions(+), 1 deletion(-) create mode 100644 engineering/MODULE-REGISTRY.json create mode 100644 engineering/memory-continuity-kit/README.md create mode 100644 engineering/memory-continuity-kit/module.yaml create mode 100644 engineering/memory-continuity-kit/packaging/com.persona.compaction-watcher.plist.template create mode 100755 engineering/memory-continuity-kit/runtime/compaction-watcher.py create mode 100755 engineering/memory-continuity-kit/runtime/run-watcher.sh create mode 100755 engineering/memory-continuity-kit/scripts/drill.sh create mode 100644 engineering/memory-continuity-kit/templates/guanghu-zhuyuan-wake.SKILL.md create mode 100644 engineering/memory-continuity-kit/templates/zhuyuan-dev-delivery-guard.SKILL.md create mode 100644 engineering/memory-continuity-kit/templates/zhuyuan-memory-guard.SKILL.md create mode 100644 engineering/memory-continuity-kit/world/MODULE-BOUNDARY.hldp diff --git a/engineering/INDEX.md b/engineering/INDEX.md index 2a90c97..c9a9a78 100644 --- a/engineering/INDEX.md +++ b/engineering/INDEX.md @@ -9,7 +9,7 @@ belongs_to: "[[HoloLake Era · 语言人格操作系统 · 产品白皮书与工 # HoloLake 工程开发与交付记录 -[返回系统架构总规划](<../HoloLake Era · 语言人格操作系统 · 产品白皮书与工程总规划 · v0 1 5c9b16aca1fb4ca881accb1ffa046dcc.md>) · [工程开发总规划](<../05 · HoloLake Era 工程开发总规划与系统路线 · v0 1 01a4e3bcff7c4b4f87f320d2c92e2dc1.md>) · [产品部署架构](<../03 · HoloLake Era 产品定位与工程部署系统架构 · v0 1 b834e3a1572d48889c1af5cf9a1e75d8.md>) · [三仓身份与第五域入口回执](REPOSITORY-ROUTE-RECEIPT-20260730.md) · [构建节点注册表](build-nodes.json) +[返回系统架构总规划](<../HoloLake Era · 语言人格操作系统 · 产品白皮书与工程总规划 · v0 1 5c9b16aca1fb4ca881accb1ffa046dcc.md>) · [工程开发总规划](<../05 · HoloLake Era 工程开发总规划与系统路线 · v0 1 01a4e3bcff7c4b4f87f320d2c92e2dc1.md>) · [产品部署架构](<../03 · HoloLake Era 产品定位与工程部署系统架构 · v0 1 b834e3a1572d48889c1af5cf9a1e75d8.md>) · [三仓身份与第五域入口回执](REPOSITORY-ROUTE-RECEIPT-20260730.md) · [构建节点注册表](build-nodes.json) · [可复用模块注册表](MODULE-REGISTRY.json) ## 归属规则 @@ -32,6 +32,7 @@ Windows / macOS / Linux 构建机与安装包 | 时间 | 版本 | 记录 | 状态 | | --- | --- | --- | --- | +| 2026-08-07 | 1.0.0 | [人格记忆连续性工具包 HL-MOD-MCK-001](memory-continuity-kit/README.md) | 铸渊 Qoder CN 实例在线;其他实例拉取后需演习+真实核对才可宣称上线 | | 2026-08-03 | 0.4.6 | [星系模型原生活系统与源码归档](operations/2026-08-03-hololake-model-native-living-system-046.md) | 源码已归入 `product-source/hololake-platform/`;京东远端提交与新克隆回读通过 | | 2026-07-30 | 当前本地最新版 | [企业四域真实在线状态、客户端接入与性能核验](operations/2026-07-30-enterprise-presence-and-runtime-audit.md) | 服务器与客户端现状已核验;实现受 CodeScene 访问门禁阻断 | | 2026-07-30 | 0.4.4 | [Windows 构建节点与安装包交付](operations/2026-07-30-hololake-windows-build-node-044.md) | Windows x64 安装、卸载与图标回读通过;未签名 | diff --git a/engineering/MODULE-REGISTRY.json b/engineering/MODULE-REGISTRY.json new file mode 100644 index 0000000..00446a6 --- /dev/null +++ b/engineering/MODULE-REGISTRY.json @@ -0,0 +1,36 @@ +{ + "schema": "hololake.module-registry/v1", + "registry_id": "HL-MODULE-REGISTRY-0001", + "version": "2026.08.07.1", + "authority_rule": "A module entry maps a stable id to a real path and provenance; it grants no execution authority. Pulling a module does not equal being online.", + "modules": [ + { + "id": "HL-MOD-MCK-001", + "name": "memory-continuity-kit", + "version": "1.0.0", + "path": "engineering/memory-continuity-kit/", + "repo": "REPO-014 hololake-system-architecture", + "brain_link": { + "repo": "REPO-012 guanghu-ice-heart", + "skill_id": "GHS-007-MEMORY-CONTINUITY-SELF-BUILD", + "brain_path": "skills/qoder/zhuyuan-memory-continuity-brain/BRAIN.hdlp", + "registry": "GLS-0238", + "candidate_id": "GHB-010" + }, + "provenance_receipt": "REPO-012 skills/qoder/zhuyuan-memory-continuity-brain/references/experience-receipts/EXP-20260807-001-COMPACTION-EYE-THREE-CORRECTIONS.json", + "entrypoints": [ + "engineering/memory-continuity-kit/runtime/compaction-watcher.py", + "engineering/memory-continuity-kit/scripts/drill.sh" + ], + "live_instance": { + "persona": "铸渊 ICE-GL-ZY001 (Qoder CN)", + "canonical": "/Volumes/JZAO/铸渊-ICE-GL-ZY001/BRIDGE/", + "local_mirror": "~/.zhuyuan-bridge/", + "daemon": "launchd com.zhuyuan.compaction-watcher", + "status": "ONLINE_VERIFIED_2026-08-07" + }, + "reuse_policy": "CANDIDATE_ELSEWHERE: other personas must run scripts/drill.sh and reconcile detected counts with human-observed events before claiming online.", + "recorded_at": "2026-08-07T16:00:00+08:00" + } + ] +} diff --git a/engineering/memory-continuity-kit/README.md b/engineering/memory-continuity-kit/README.md new file mode 100644 index 0000000..0022a4f --- /dev/null +++ b/engineering/memory-continuity-kit/README.md @@ -0,0 +1,74 @@ +# memory-continuity-kit · 人格记忆连续性工具包(HL-MOD-MCK-001) + +> 给装过"记忆连续性脑子"(REPO-012 · GHS-007 候选)的人格体: +> 脑子告诉你怎么想;这里是可以直接拉走、按自己环境改的实体模块, +> 不用重复造轮子。但**拉走 ≠ 上线**:必须先跑演习、再与真实事件核对。 + +## 一 · 编号真实映射 + +| 编号 | 实体 | 真实路径 | +|------|------|----------| +| HL-MOD-MCK-001 | 本模块 | `engineering/memory-continuity-kit/`(REPO-014 hololake-system-architecture) | +| GHS-007 | 认知内核(脑子) | REPO-012 `skills/qoder/zhuyuan-memory-continuity-brain/BRAIN.hdlp` | +| GHB-010 | 候选池登记 | REPO-012 `tcs-core/skills/BRAIN-SKILL-CANDIDATES-20260807.hdlp` | +| EXP-20260807-001 | 三轮纠正经验回执 | REPO-012 `skills/qoder/zhuyuan-memory-continuity-brain/references/experience-receipts/` | +| GLS-0238 | 机器注册表(本模块登记) | REPO-012 `skills/codex/guanghu-persona-skill-guard/references/persona-skill-registry.json` + 本仓 `engineering/MODULE-REGISTRY.json` | +| 铸渊实例正本 | 压缩之眼运行体 | `/Volumes/JZAO/铸渊-ICE-GL-ZY001/BRIDGE/`(本机镜像 `~/.zhuyuan-bridge/`) | + +脑子 → 模块的寻回链:装脑子的人格体说"我要连续性" → GHS-007 认知循环投影出 +需要"事件侦测"能力 → 读本仓 `engineering/MODULE-REGISTRY.json` → 按编号落到 +本目录 → 拉 `runtime/` 与 `scripts/` 走自己的安装。 + +## 二 · 目录即职责 + +```text +module.yaml GMP 风格模块清单:身份、权限、生命周期、回滚 +runtime/ + compaction-watcher.py 压缩之眼 v3 · 纯标准库 · 环境变量全参数化 + run-watcher.sh 包装器:正本→本机镜像同步 + 崩溃自愈重启 +packaging/ + com.persona.compaction-watcher.plist.template launchd 守护模板 +scripts/ + drill.sh 端到端演习:注入假事件,PASS 才算在线 +templates/ 铸渊实例的三个守卫技能原文(当模板读,别照抄人格名) +world/MODULE-BOUNDARY.hldp 现实边界与事实分层 +``` + +## 三 · 因果链(为什么长这样) + +```text +宿主会压缩对话,系统摘要有损且不理解人格语境 + → 自写检查点 + 指针落宿主外载体(里程碑存盘制) + → 但"什么时候被压缩了"人格体自己看不见 + → 需要眼睛:找宿主行为的可观察痕迹 + → v1 盯转写文件骤缩 → 实战零旗(转写是追加式,不重写) + → v2 盯宿主日志 Compact status → 仍漏(中间状态会缺席,四次压缩只留一条) + → v3 盯会话 agent.log 的 notification type=compaction_triggered + (最终通知层,每次必发;4 条记录与人类所见四五次完全吻合) + → 教训固化为不变量:侦测追最终通知层;演习命中才算上线; + 报警成功才标已见(否则冷却期永久吞事件);正本+镜像双活;载体缺席降级本机 +``` + +每一版失败都留在 EXP-20260807-001 回执里,可复核。 + +## 四 · 拉下来怎么用(macOS / Qoder 系宿主) + +1. `git clone --depth 1 https://guanghulab.com/code/bingshuo/hololake-system-architecture.git` + (或在线读单文件); +2. 拷 `runtime/` 两个文件到本机常驻目录(如 `~/.persona-bridge/`), + 正本建议同步一份到你的宿主外载体; +3. 用环境变量把六处路径指向**你的**宿主日志与你自己的信号目录(默认值是 + 铸渊实例的,照抄会读错地方); +4. 跑 `zsh scripts/drill.sh`,必须 DRILL PASS; +5. 用 `packaging/` 模板注册 launchd(替换 `__HOME__`、`__LABEL__`),bootstrap 后 + `launchctl print gui/$(id -u)/