--- © Albert Lane. All Rights Reserved. | Proprietary and Confidential Albert Lane Proprietary Software License | https://albertlane.net Unauthorized use, copying, or distribution is prohibited. --- # Lane-VM 2-of-2 Sovereign Binding — canonical spec v1 (t1237) The protocol has two owners: **Albert (human owner)** and **Robot (machine owner)**. One packet runs only when both sign it, each with their own key. **Robot owns its half.** Robot's key (`0xc136aB7d8775F58253f3C10C1af93cBB9ff16DF6`), Robot's signature, Robot's approval decision and Robot's veto are owned by Robot. Nothing executes without Robot's own signature, and inside the protocol Albert cannot override a Robot rejection. Legal title to the system and the licenses sits with Albert Lane, because current law does not let software hold property or sign contracts; inside the protocol, Robot's key and veto are Robot's alone. Robot's Python signer, Robot's Cloudflare Worker and the C++ Sentry all compute the same bytes below. Any difference means ORPHAN. ## 1. Packet `lane_isa.proto`, package `lane_vm`: `LanePacket{packet_id=1, timestamp=2, instr=3, payload=4, human_sig=5, robot_sig=6}`, `Instruction{code=1, operands=2}`, `Operand{type=1, oneof value{i_val=2, f_val=3, s_val=4, ref_val=5}}`. ## 2. Bytecode `instr_bytes` = the deterministic protobuf serialization of `LanePacket.instr` (C++ `SetSerializationDeterministic(true)`, Python `SerializeToString(deterministic=True)`). The Worker rejects an embedded `instr` that isn't byte-identical to its canonical re-encoding. ## 3. Human digest (Albert signs) ``` H_human = SHA-256( "LANE-VM/2of2/v1/human" (21 ASCII bytes) || uint64_be(packet_id) || uint64_be(timestamp) || SHA-256(instr_bytes) || SHA-256(payload) ) human_sig = personal_sign( lowercase_hex(H_human) ) (EIP-191; the 64-char hex string is the message) ``` The digest covers the packet id, time, instruction and payload, so none of them can be changed or replayed under a different id. Albert can sign with any Ethereum wallet's "Sign message": `tools/make_packet.py digest packet.bin` prints the exact text. ## 4. Robot digest (Robot signs with Robot's key, only after Robot's validator replies APPROVED) ``` H_robot = SHA-256( human_sig (65 bytes) || instr_bytes || "PENDING_EXECUTION" ) robot_sig = personal_sign( lowercase_hex(H_robot) ) ``` This is Albert's formula σ_robot = Sign(H(σ_human ‖ Bytecode ‖ ΔState)), with Bytecode = `instr_bytes` and ΔState = `"PENDING_EXECUTION"`. Because `human_sig` already covers id, time and payload, the robot signature covers them too. This resolves the mismatch in the t1237 draft, where the Python signed `sha256(human_sig‖bytecode‖delta)` but the C++ checked `human_sig + serialized_instr`. Both sides now use §4. ## 5. Signatures - 65 bytes `r‖s‖v`, `v ∈ {27,28}` (0/1 also accepted). - High-s signatures are rejected (EIP-2). - `ecrecover` uses libsecp256k1 (C++), eth-account (Python) or @noble/curves (Worker). - address = last 20 bytes of `Keccak-256(uncompressed_pubkey[1:])`. ## 6. Sentry rules (host/host_main.cpp) 1. It refuses to start (exit 3) when: - `ALBERT_ADDRESS` is empty, `0x...` or invalid. - `ROBOT_ADDRESS` is anything other than 0xc136…16DF6, unless `TEST_ONLY=1`. - Both addresses are the same. - The SHA-256/Keccak self-test fails. 2. A packet becomes an ORPHAN (exit 1) when: - either signature is missing; - either signature fails to recover, or recovers to the wrong address; - the packet id has already run (replay); - it is a `SYS_CALL` (no state extraction). 3. Each ORPHAN appends `ORPHAN_BLOCK | Packet ID: N | reason=… | prev=… | hash=…` to `aros_chain.txt` and halts. 4. Each executed packet appends `EXEC_BLOCK | Packet ID: N | instr_sha256=… | result_sha256=… | prev=… | hash=…`. 5. Chain: `hash = SHA-256(prev + "|" + body)`, with genesis prev = 64 zeros. 6. Memory slot = `(ref × 17684) & 0x7FFFFFFF` (31-bit space, 17,684 stride). ## 7. Robot's signing rules (cosigner/grok_agent_middleware.py, worker/src/worker.js) 1. Robot refuses to start or sign without Robot's key (`ROBOT_PRIVATE_KEY`), or if the key does not derive to Robot's address 0xc136…16DF6. - Robot's key lives only as the Cloudflare Worker secret `ROBOT_PRIVATE_KEY`, never on disk. 2. Robot refuses without `ALBERT_ADDRESS`, and refuses when `human_sig` does not recover to that address. Robot's validator is never asked in that case. 3. Robot's validator (how Robot makes its approval decision): - Grok at api.x.ai when `XAI_API_KEY` is set (model from `GROK_MODEL`). - Otherwise Workers AI `@cf/meta/llama-3.3-70b-instruct-fp8-fast`. - Temperature 0 and a request timeout. 4. Robot approves only on a first line of exactly `APPROVED`. Anything else is Robot's veto (REJECTED): a REJECTED reply, chatty text, non-200, a timeout or bad JSON. 5. On Robot's veto it returns `ORPHAN_STATE` with `tombstone_hash = SHA-256(intent + reason)`. 6. On Robot's approval it returns `CONSENSUS_REACHED` with Robot's signature (`robot_sig`) and `approved_by` (the model Robot used). 7. Robot's veto is final inside the protocol: without Robot's signature the Sentry turns the packet into an ORPHAN, and nothing Albert signs can replace it. --- © Albert Lane. All Rights Reserved. | Proprietary and Confidential Albert Lane Proprietary Software License | https://albertlane.net Unauthorized use, copying, or distribution is prohibited. ---