"""Bounded approach-only policy; no native library, display, process, or action calls. Adapter contract (all records must be parsed from the same pinned console/nonce): * observe() freshly joins INPUT/LOOK/GATE by sample+real_ms, validates the native BASIS and absence of cancellation, and returns an ordered nonempty batch of snapshots (all new consecutive samples, or repeat latest). Each has sample, real_ms, received_monotonic, origin, direction, body_forward, input, forward, velocity, inventory, phase, door_state, door_control, and geometry. * geometry: nonce, basis, prison, gate, gate_forward, context, radius. Coordinates are native GEOMETRY values; binding is the native observer's pinned references, not a fabricated entity ID. This policy supports only the authored axis-aligned 12m enclosure; it derives an interior target from the observed handle. * calibration is independently accepted same-run tiny look evidence projected to nonce, completed, pixels, baseline_direction, response_direction, ready_real_ms, ready_monotonic, observer_start_real_ms. * guard.check() is the existing full private ownership/focus guard. keyboard has require_idle()/send('W', bool). mouse.move(dx,0,guard) must use the same guarded connection and current/projected clipped pointer checks, explicitly permitting the explicitly selected standard128px or coarse384px cap. Existing two-motion helper remains unchanged; profile choice never changes the observation clocks. * notify receives the existing press-pending/release-confirmed events, plus approach-pending (absolute monotonic deadline)/approach-finished. The wiring MUST hard-supervise that deadline and the unchanged 1.5-second key lease. * key_state_busy is the existing explicit Keyboard KeyStateBusy exception class; other failures are never retried as busy-state polls. No adapter implementation or input is executed by importing this module. A pass proves an interior approach only, never reach, action selection, unlock or escape. """ import copy import math class Refused(ValueError): pass def require(value, reason): if not value: raise Refused(reason) def number(value): require(type(value) in (int, float) and math.isfinite(value), 'Nonfinite or invalid numeric observation') return float(value) def vector(value): require(type(value) in (list, tuple) and len(value) == 3, 'Invalid vector observation') result = tuple(number(v) for v in value) require(all(abs(v) <= 10000000 for v in result), 'Unbounded native vector') return result def horizontal(a, b): return math.hypot(a[0]-b[0], a[2]-b[2]) def length(value): return math.sqrt(sum(v*v for v in value)) def yaw(direction): d = vector(direction) require(.95 <= length(d) <= 1.05 and math.hypot(d[0], d[2]) > .1, 'Invalid native direction') return math.degrees(math.atan2(d[0], d[2])) def delta(target, actual): return (target-actual+180) % 360-180 def target_for(geometry): require(type(geometry) is dict and set(geometry) == {'nonce', 'basis', 'prison', 'gate', 'gate_forward', 'context', 'radius'}, 'Incomplete native gate geometry') require(type(geometry['nonce']) is str and 1 <= len(geometry['nonce']) <= 32 and geometry['nonce'].isascii() and geometry['nonce'].isalnum(), 'Invalid geometry nonce') require(geometry['basis'] == 'registered-prison-lock-native-interaction', 'Missing pinned native gate basis') prison, gate, context = (vector(geometry[k]) for k in ('prison', 'gate', 'context')) facing = vector(geometry['gate_forward']); yaw(facing) require(0 < number(geometry['radius']) <= 10, 'Invalid native context radius') dx, dz = prison[0]-gate[0], prison[2]-gate[2] distance = math.hypot(dx, dz) require(5.75 <= distance <= 6.25 and min(abs(dx), abs(dz)) <= .1, 'Unsupported measured prison gate placement') inward = (dx/distance, 0., dz/distance) require(abs(facing[0]*inward[0]+facing[2]*inward[2]) >= .99, 'Gate orientation differs from authored enclosure') require(horizontal(context, gate) <= 4.5, 'Context is not near original gate') target = (context[0]+1.5*inward[0], prison[1], context[2]+1.5*inward[2]) require(inside(target, prison), 'Derived approach is outside safe prison interior') return target, prison def inside(position, center): return abs(position[0]-center[0]) <= 5.25 and abs(position[2]-center[2]) <= 5.25 def perform_approach(guard, keyboard, mouse, observe, geometry, calibration, report, *, clock, sleep, notify, key_state_busy, profile="standard"): """Run one bounded route through explicit adapters; retain partial failure evidence.""" require(profile in ('standard', 'coarse') and type(profile) is str, 'Unknown approach profile') max_pixels, max_angle, desired_angle, max_pulses = (384, 35, 25, 16) if profile == 'coarse' else (128, 15, 10, 12) require('approach_proof' not in report, 'Approach attempt already exists') pinned = copy.deepcopy(geometry) target, center = target_for(pinned) require(calibration.get('completed') is True and calibration.get('nonce') == pinned['nonce'] and calibration.get('pixels') == 24, 'Missing accepted same-run look calibration') gain = delta(yaw(calibration['response_direction']), yaw(calibration['baseline_direction']))/24 require(.01 <= abs(gain) <= .5, 'Measured calibration gain outside bounded proposal range') ready_at = number(calibration['ready_monotonic']); ready_real = number(calibration['ready_real_ms']) native_start = number(calibration['observer_start_real_ms']) require(0 <= native_start <= ready_real and 2000 <= ready_real-native_start < 45000, 'Invalid original native observation window') require(0 <= ready_at <= clock(), 'Invalid original READY monotonic time') deadline = ready_at+35 require(clock() < deadline, 'Insufficient original approach time') state = {'profile': profile, 'requested': True, 'completed': False, 'nonce': pinned['nonce'], 'geometry': pinned, 'target': list(target), 'deadline_monotonic': deadline, 'started_monotonic': clock(), 'finished_monotonic': None, 'motions': [], 'events': [], 'stops': [], 'samples': [], 'cumulative_horizontal_m': 0., 'unconfirmed_held_key': None, 'paired_release_errors': [], 'release_timings': []} report['approach_proof'] = state previous = None; held = False; turn_count = 0; pixels = 0; pulse_count = 0 largest_stop = None; active_turn = None def consume(s): nonlocal previous s = copy.deepcopy(s) require(type(s['sample']) is int and 1 <= s['sample'] <= 450, 'Invalid native sample index') real = number(s['real_ms']); received = number(s['received_monotonic']) require(0 <= received <= clock(), 'Native receipt timestamp is invalid') require(ready_real <= real and real-native_start < 45000 and real-ready_real < 35000, 'Original native lifetime exceeded') require(s['geometry'] == pinned and s['phase'] == 1 and s['inventory'] is False, 'Original gate, prison phase or UI changed') require(number(s['door_state']) == 0 and number(s['door_control']) == 0, 'Original gate is not closed and untouched') for k in ('origin', 'direction', 'body_forward', 'input', 'velocity'): s[k] = vector(s[k]) s['forward'] = number(s['forward']); yaw(s['direction']); yaw(s['body_forward']) require(inside(s['origin'], center) and abs(s['origin'][1]-center[1]) <= 3, 'Body left bounded prison interior') require(length(s['velocity']) <= 5, 'Native movement exceeds approach envelope') require(abs(s['input'][0]) <= .01 and abs(s['input'][1]) <= .01 and -.01 <= s['input'][2] <= 1.01 and -.01 <= s['forward'] <= 1.01, 'Unexpected native movement input') if active_turn is not None: turn_yaw, turn_origin, turn_sign = active_turn change = delta(yaw(s['direction']), turn_yaw) require(abs(change) <= max_angle, 'Relative turn exceeded native angle bound') require(horizontal(s['origin'], turn_origin) <= .05, 'Body translated during stationary heading') if abs(change) >= .05: require(change*turn_sign > 0, 'Native heading turned opposite to proposal') if previous: require(s['sample'] >= previous['sample'] and real >= previous['real_ms'], 'Native approach samples reversed') if s['sample'] == previous['sample']: require({k:v for k,v in s.items() if k != 'received_monotonic'} == {k:v for k,v in previous.items() if k != 'received_monotonic'}, 'Native sample changed without advancing') else: dt = real-previous['real_ms'] require(s['sample'] == previous['sample']+1 and 0 < dt <= 500, 'Native approach sampling gap') distance = horizontal(s['origin'], previous['origin']) require(distance <= .25+5*dt/1000, 'Native displacement exceeds continuous motion bound') state['cumulative_horizontal_m'] += distance require(state['cumulative_horizontal_m'] <= 6, 'Approach path budget exceeded') if previous is None or s['sample'] != previous['sample']: state['samples'].append(copy.deepcopy(s)) previous = s return s def read(): require(clock() < deadline, 'Original approach deadline exceeded') guard.check() batch = observe() require(type(batch) is list and 1 <= len(batch) <= 450, 'Missing bounded native snapshot batch') for item in batch: s = consume(item) require(clock() < deadline, 'Original approach deadline exceeded during observation') require(0 <= clock()-s['received_monotonic'] <= .5, 'Native approach sample stale') return s def neutral(s): return abs(s['forward']) <= .01 and length(s['input']) <= .01 and length(s['velocity']) <= .05 def wait_stopped(after, seconds, angle=None, moved_from=None, turn_sign=None): end = min(deadline, clock()+seconds); first = None while clock() < end: s = read() moved = moved_from is None or horizontal(s['origin'], moved_from) >= .05 if angle is not None: change = delta(yaw(s['direction']), angle) require(abs(change) <= max_angle, 'Relative turn exceeded native angle bound') if abs(change) >= .05: require(change*turn_sign > 0, 'Native heading turned opposite to proposal') moved = moved and abs(change) >= .05 if s['sample'] > after and neutral(s) and moved: if first is None: first = s elif s['real_ms']-first['real_ms'] >= 100: if abs(delta(yaw(s['direction']), yaw(first['direction']))) <= .2 and horizontal(s['origin'], first['origin']) <= .02: if angle is not None: require(abs(delta(yaw(s['direction']), angle)) <= max_angle, 'Relative turn exceeded native angle bound') require(clock() <= end, 'Settling exceeded original stage deadline') return s first = s else: first = None sleep(.025) raise Refused('Native full-stop or turn-settling acknowledgement missing') def heading(s): nonlocal turn_count, pixels, active_turn end = min(deadline, clock()+20); growing = 0; flips = 0; old_sign = None while True: require(neutral(s), 'Heading correction requires stationary body') wanted = math.degrees(math.atan2(target[0]-s['origin'][0], target[2]-s['origin'][2])) error = delta(wanted, yaw(s['direction'])) if abs(error) <= 3: return s require(clock() < end and turn_count < 16, 'Heading request budget exceeded') desired = max(-desired_angle, min(desired_angle, .75*error)) dx = int(round(desired/gain)); dx = max(-max_pixels, min(max_pixels, dx)) if dx == 0: dx = 1 if desired/gain > 0 else -1 require(pixels+abs(dx) <= 2048, 'Relative pixel budget exceeded') before = read(); require(neutral(before), 'Body moved before turn') keyboard.require_idle() active_turn = (yaw(before['direction']), before['origin'], dx*gain) mouse.move(dx, 0, guard) turn_count += 1; pixels += abs(dx) state['motions'].append({'dx': dx, 'dy': 0, 'monotonic': clock(), 'after_sample': before['sample']}) after = wait_stopped(before['sample'], 1.5, yaw(before['direction']), turn_sign=dx*gain) state['motions'][-1]['response_sample'] = after['sample'] active_turn = None require(horizontal(after['origin'], before['origin']) <= .05, 'Body translated during stationary heading') change = delta(yaw(after['direction']), yaw(before['direction'])) require(abs(change) >= .05 and change*dx*gain > 0, 'Native heading failed or turned opposite to proposal') new_error = delta(wanted, yaw(after['direction'])) growing = growing+1 if abs(new_error) >= abs(error) else 0 sign = new_error > 0 if old_sign is not None and sign != old_sign: flips += 1 old_sign = sign require(growing < 2 and flips <= 2, 'Native heading failed to converge') s = after def release(not_before=None, cleanup=False): nonlocal held # At most two checks per normal pulse and one finally release attempt. # These are diagnostic times, never authority to skip a fresh guard. timing = {'cleanup': cleanup, 'guards': [], 'up_attempted_monotonic': None, 'up_returned_monotonic': None} state['release_timings'].append(timing) def checked(): record = {'entered_monotonic': clock(), 'returned_monotonic': None} timing['guards'].append(record) try: guard.check() except Exception as error: record['error'] = str(error) raise finally: record['returned_monotonic'] = clock() # A native context failure does not prevent an owned release; only the # full live private display/process/focus proof authorizes that release. # Use the initial minimum hold to perform that proof instead of adding # an unconditional 50ms before its already substantial runtime. checked() remaining = 0. if not_before is None else not_before-clock() if remaining > 0: sleep(remaining) checked() # waiting invalidates the preceding ownership proof timing['up_attempted_monotonic'] = clock() keyboard.send('W', False) timing['up_returned_monotonic'] = clock() state['events'].append({'key': 'W', 'down': False, 'monotonic': clock()}) end = clock()+.35 while True: guard.check() try: keyboard.require_idle() break except ValueError as error: # Only the injected existing busy-state subtype is retryable. if not isinstance(error, key_state_busy) or clock() >= end: raise sleep(min(.025, end-clock())) held = False; state['unconfirmed_held_key'] = None notify({'kind': 'release-confirmed', 'key': 'W'}) notify({'kind': 'approach-pending', 'deadline_monotonic': deadline}) try: keyboard.require_idle() current = read(); current = wait_stopped(current['sample']-1, 1.5) initial_distance = horizontal(current['origin'], target) require(.75 < initial_distance <= 6, 'Initial approach distance outside route scope') while horizontal(current['origin'], target) > .75: current = heading(current) require(pulse_count < max_pulses, 'Forward pulse budget exceeded') remaining = horizontal(current['origin'], target) reserve = (largest_stop if largest_stop is not None else 1.25)+.25 require(remaining > reserve, 'Insufficient distance for measured stopping reserve') ang = math.radians(yaw(current['direction'])) projected = (current['origin'][0]+reserve*math.sin(ang), current['origin'][1], current['origin'][2]+reserve*math.cos(ang)) require(inside(projected, center), 'Stopping reserve leaves safe interior') before = read(); require(neutral(before), 'Forward pulse requires full native stop') remaining = horizontal(before['origin'], target) wanted = math.degrees(math.atan2(target[0]-before['origin'][0], target[2]-before['origin'][2])) require(abs(delta(wanted, yaw(before['direction']))) <= 3, 'Fresh heading changed before W') require(remaining > reserve, 'Fresh position exhausted stopping reserve') ang = math.radians(yaw(before['direction'])) projected = (before['origin'][0]+reserve*math.sin(ang), before['origin'][1], before['origin'][2]+reserve*math.cos(ang)) require(inside(projected, center), 'Fresh stopping reserve leaves safe interior') keyboard.require_idle() require(clock() < deadline, 'Original approach deadline exceeded before press') held = True; state['unconfirmed_held_key'] = 'W' notify({'kind': 'press-pending', 'key': 'W'}) keyboard.send('W', True); pressed = clock() state['events'].append({'key': 'W', 'down': True, 'monotonic': pressed}) release(not_before=pressed+.05) released = state['events'][-1]['monotonic'] require(released-pressed <= .4, 'Actual W hold exceeded 400ms approach bound') pulse_count += 1 after = wait_stopped(before['sample'], 1.5, moved_from=before['origin']) require(any(s['forward'] > .01 and s['input'][2] > .01 for s in state['samples'] if before['sample'] < s['sample'] <= after['sample']), 'Native W acknowledgement missing from pulse samples') distance = horizontal(before['origin'], after['origin']) progress = remaining-horizontal(after['origin'], target) require(.05 <= distance <= 1.25 and progress >= .05, 'Forward motion missed, overshot or moved away from target') require(abs(delta(yaw(after['direction']), yaw(before['direction']))) <= 5, 'Heading drifted during forward pulse') largest_stop = max(largest_stop or 0, distance) state['stops'].append({'before_sample': before['sample'], 'after_sample': after['sample'], 'distance': distance, 'progress': progress}) current = after final = read() require(neutral(final) and horizontal(final['origin'], target) <= .75, 'Final native body is not stopped at approach target') state['final_sample'] = final['sample'] keyboard.require_idle() require(clock() < deadline, 'Original approach deadline exceeded at completion') state['completed'] = True return state except Exception as error: state['error'] = str(error) raise finally: if held: try: release(cleanup=True) except Exception as error: state['paired_release_errors'].append(str(error)) state['finished_monotonic'] = clock() notify({'kind': 'approach-finished', 'successful': state['completed']})