"""CSS / external JavaScript / events / actual Monaco checks in a private QEMU.
The HTTP peer supplies controlled bytes over the guest's native NIC. QMP only
sends real keyboard/mouse input and captures the native framebuffer. No browser
state is injected through a host browser, guest debugger or synthetic DOM.
"""
import hashlib
import html
import json
import pathlib
import re
import threading
import time
import uuid
from datetime import datetime, timezone
from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer
from urllib.parse import urlsplit
from PIL import Image
from NativeCSharpEvidence import CSHARP_PROOF, csharp_frame_stats, verify_readback, website_palette
WINDOW = re.compile(r'^XFE_WINDOW_STATE\|(\d+)\|Browser\|(-?\d+)\|(-?\d+)\|(\d+)\|(\d+)\|([01])\|([01])\|([01])$', re.M)
PAGE = re.compile(r'XFE_BROWSER_STATE_BEGIN\r?\n([^\n]*)\n(.*?)\r?\nXFE_BROWSER_STATE_END', re.S)
MODEL = re.compile(r'XFE_MONACO_VALUE_BEGIN\r?\n(.*?)\r?\nXFE_MONACO_VALUE_END', re.S)
class BrowserFixture:
"""Loopback-only fixture with request evidence and deterministic resources."""
def __init__(self, nonce):
self.nonce = nonce
self.requests = []
self.lock = threading.Lock()
quoted = json.dumps(nonce)
self.resources = {
'/External.css': ('text/css', '''html,body{margin:0;padding:0;background:#F1F6FB;color:#162638;font-family:monospace;font-size:16px}
#Swatch{position:absolute;left:24px;top:24px;width:160px;height:64px;box-sizing:border-box;border:4px solid #75C9F5;background:#1877C9}
#Click{position:absolute;left:24px;top:104px;width:200px;height:40px;box-sizing:border-box;background:#4086B8;color:white;border:2px solid #75C9F5}
#Input{position:absolute;left:24px;top:160px;width:300px;height:60px;box-sizing:border-box;background:white;color:#162638;border:2px solid #4086B8;padding:4px}
#Outputs{position:absolute;left:360px;top:24px;width:400px;font-size:13px;line-height:20px}'''),
'/Classic.js': ('application/javascript', "window.fixtureOrder=['classic'];"),
'/Defer.js': ('application/javascript', '''window.fixtureOrder.push('defer');
document.getElementById('Ready').textContent='External ready '+NONCE+' '+fixtureOrder.join(',');
document.getElementById('Click').addEventListener('click',function(){document.getElementById('ClickResult').textContent='Button clicked '+NONCE;});
document.getElementById('Input').addEventListener('input',function(){document.getElementById('InputResult').textContent='Input typed '+this.value+' '+NONCE;});
setTimeout(function(){document.getElementById('Timer').textContent='Timer fired '+NONCE;},1200);
requestAnimationFrame(function(){document.getElementById('Frame').textContent='Animation frame '+NONCE;});
var external=document.createElement('script');external.src='/Dynamic.js';document.head.appendChild(external);'''.replace('NONCE', quoted)),
'/Dynamic.js': ('application/javascript', "window.fixtureOrder.push('dynamic');document.getElementById('Dynamic').textContent='Dynamic loaded '+" + quoted + ";"),
}
document = '''<!doctype html><html><head><title>XFE pipeline</title>
<link rel=stylesheet href=/External.css><script src=/Classic.js></script><script defer src=/Defer.js></script></head>
<body><div id=Swatch></div><button id=Click>Click native event</button><textarea id=Input></textarea>
<div id=Outputs><div id=Ready>External pending</div><div id=Dynamic>Dynamic pending</div><div id=ClickResult>Click pending</div>
<div id=InputResult>Input pending</div><div id=Timer>Timer pending</div><div id=Frame>Frame pending</div><div>NONCE</div></div></body></html>'''
self.resources['/Index'] = ('text/html', document.replace('NONCE', html.escape(nonce)))
fixture = self
class Handler(BaseHTTPRequestHandler):
protocol_version = 'HTTP/1.1'
def log_message(self, *_):
pass
def do_GET(self):
path = urlsplit(self.path).path
with fixture.lock:
fixture.requests.append({'Path': self.path, 'Utc': datetime.now(timezone.utc).isoformat(),
'Host': self.headers.get('Host'), 'Peer': self.client_address[0]})
self.close_connection = True
resource = fixture.resources.get(path)
if resource is None:
self.send_error(404)
return
content_type, source = resource
body = source.encode('utf-8')
try:
self.send_response(200)
self.send_header('Content-Type', content_type + '; charset=utf-8')
self.send_header('Content-Length', str(len(body)))
self.send_header('Connection', 'close')
self.end_headers()
self.wfile.write(body)
self.wfile.flush()
except (BrokenPipeError, ConnectionResetError):
pass
self.server = ThreadingHTTPServer(('127.0.0.1', 0), Handler)
self.server.daemon_threads = True
self.thread = threading.Thread(target=self.server.serve_forever, kwargs={'poll_interval': .1}, daemon=True)
self.thread.start()
@property
def address(self):
return f'http://10.0.2.2:{self.server.server_port}/Index'
def close(self):
self.server.shutdown()
self.server.server_close()
self.thread.join(timeout=2)
def _monaco_frame_stats(frame, viewport, scale):
"""Measure real glyph ink in the controlled page's configured 20px lines.
This does not synthesize or OCR code. The actual getValue assertion verifies
text; these independent pixel bands verify its multi-line native paint.
The header, gutter and pointer are kept outside this region by the caller.
"""
vx, vy, width, _ = viewport
lines = []
for index in range(4):
x, y, w, h = vx + 42, vy + 28 + index * 20, min(600, width - 42), 20
native = (round(x * scale), round(y * scale), round((x + w) * scale), round((y + h) * scale))
crop = frame.crop(native).convert('RGB')
columns, rows = set(), set()
ink = blue = green = 0
for row in range(crop.height):
for column in range(crop.width):
pixel = crop.getpixel((column, row))
# The editor's dark background/current-line borders are below
# this threshold; syntax colors and foreground glyphs exceed it.
if .2126 * pixel[0] + .7152 * pixel[1] + .0722 * pixel[2] >= 78:
ink += 1; columns.add(column); rows.add(row)
if all(abs(pixel[channel] - (0x56, 0x9C, 0xD6)[channel]) <= 12 for channel in range(3)):
blue += 1
if any(all(abs(pixel[channel] - color[channel]) <= 12 for channel in range(3)) for color in ((0x60, 0x8B, 0x4E), (0x6A, 0x99, 0x55))):
green += 1
span = max(columns) - min(columns) + 1 if columns else 0
glyphs = ink >= 35 * scale * scale and len(columns) >= 24 * scale and len(rows) >= 4 * scale and span >= 40 * scale
lines.append({'Line': index + 1, 'CssBounds': [x, y, w, h], 'NativeBounds': list(native),
'InkPixels': ink, 'InkColumns': len(columns), 'InkRows': len(rows), 'InkSpan': span,
'BlueSyntaxPixels': blue, 'GreenCommentPixels': green, 'HasTextGlyphDistribution': glyphs})
return {'ConfiguredLineHeightCss': 20, 'EditorHeaderHeightCss': 28, 'Lines': lines,
'ReadyPainted': all(line['HasTextGlyphDistribution'] for line in lines[:3])
and lines[0]['GreenCommentPixels'] >= 8 * scale * scale
and lines[1]['BlueSyntaxPixels'] >= 8 * scale * scale}
def _monaco_fourth_line_delta(before, after, native_bounds):
"""New text ink only: changing a dark selection/current-line fill is insufficient."""
old = before.crop(native_bounds).convert('RGB'); new = after.crop(native_bounds).convert('RGB')
added = set(); pixels = 0
for row in range(new.height):
for column in range(new.width):
old_pixel = old.getpixel((column, row)); pixel = new.getpixel((column, row))
old_ink = .2126 * old_pixel[0] + .7152 * old_pixel[1] + .0722 * old_pixel[2] >= 78
new_ink = .2126 * pixel[0] + .7152 * pixel[1] + .0722 * pixel[2] >= 78
if new_ink and not old_ink:
pixels += 1; added.add(column)
return {'NewInkPixels': pixels, 'NewInkColumns': len(added)}
def run_browser_checks(qmp, text, wait_log, screenshot, native_width, native_height, scale, pointer):
checks = []
evidence = {'Kind': 'NativeBrowserPipeline', 'NativeWidth': native_width, 'NativeHeight': native_height,
'Scale': scale, 'Checks': checks, 'Passed': False,
'Boundary': 'Original bounded CSS layout and classic-script interpreter; no full Chromium, complete CSS, workers, GPU canvas or verified HTTPS claim.'}
nonce = 'Guest-' + uuid.uuid4().hex[:12]
fixture = BrowserFixture(nonce)
output = None
def key(code, down):
qmp('input-send-event', {'events': [{'type': 'key', 'data': {'down': down, 'key': {'type': 'qcode', 'data': code}}}]})
time.sleep(.025)
def tap(code):
key(code, True); key(code, False)
def chord(modifier, code):
key(modifier, True); tap(code); key(modifier, False)
def type_text(value):
simple = {'.': 'dot', '/': 'slash', '-': 'minus', ' ': 'spc', '\n': 'ret'}
shifted = {':': 'semicolon', '_': 'minus', '?': 'slash'}
for character in value:
if character in shifted: chord('shift', shifted[character])
elif character.isupper(): chord('shift', character.lower())
else: tap(simple.get(character, character))
def move(x, y):
target = [round(x * scale), round(y * scale)]
while pointer != target:
dx = max(-80, min(80, target[0] - pointer[0])); dy = max(-80, min(80, target[1] - pointer[1]))
qmp('input-send-event', {'events': [{'type': 'rel', 'data': {'axis': 'x', 'value': dx}}, {'type': 'rel', 'data': {'axis': 'y', 'value': dy}}]})
pointer[0] += dx; pointer[1] += dy
time.sleep(.018)
def click(x, y):
move(x, y)
for down in (True, False):
qmp('input-send-event', {'events': [{'type': 'btn', 'data': {'down': down, 'button': 'left'}}]})
time.sleep(.08)
def capture(name):
nonlocal output
time.sleep(.15)
path = pathlib.Path(screenshot(name)).resolve()
output = path.parent
with Image.open(path) as saved:
assert saved.size == (native_width, native_height), saved.size
frame = saved.convert('RGB').copy()
evidence.setdefault('Screenshots', []).append({'Path': str(path), 'Sha256': hashlib.sha256(path.read_bytes()).hexdigest()})
return frame
def page_bodies(start):
return [match.group(2).replace('\r', '') for match in PAGE.finditer(text()[start:])]
def wait_body(marker, start, timeout=20):
deadline = time.monotonic() + timeout
while time.monotonic() < deadline:
bodies = page_bodies(start)
for body in reversed(bodies):
if marker in body: return body
log = text()
assert '[FAILFAST]' not in log and '*** UNHANDLED EXCEPTION' not in log and 'CPU EXCEPTION:' not in log, log[-4000:]
time.sleep(.05)
raise AssertionError('Native browser state timeout: ' + marker + '\n' + text()[start:][-7000:])
def navigate(address):
start = len(text()); chord('ctrl', 'l'); type_text(address); tap('ret')
wait_log('XFE_BROWSER_NAVIGATED|', start, 30)
return start
def browser_bounds(start):
deadline = time.monotonic() + 10
while time.monotonic() < deadline:
matches = list(WINDOW.finditer(text()[start:]))
if matches:
parts = matches[-1].groups()
return {'Id': int(parts[0]), 'X': int(parts[1]), 'Y': int(parts[2]), 'Width': int(parts[3]), 'Height': int(parts[4])}
time.sleep(.05)
raise AssertionError('Browser window geometry log missing')
def count_color(frame, bounds, rgb, tolerance=3):
x, y, width, height = bounds
crop = frame.crop((round(x * scale), round(y * scale), round((x + width) * scale), round((y + height) * scale)))
return sum(all(abs(pixel[channel] - rgb[channel]) <= tolerance for channel in range(3)) for pixel in crop.getdata())
try:
start = len(text()); click(60, 308)
wait_log('XFE_DESKTOP_ACTIVE|Browser', start)
window = browser_bounds(start)
viewport = (window['X'] + 2, window['Y'] + 67, window['Width'] - 4, window['Height'] - 96)
evidence['BrowserWindow'] = window; evidence['BrowserViewport'] = viewport
capture('Browser-Pipeline-Start') # Establish the private evidence directory even if a later request fails.
wait_log('XFE_NETWORK_DHCP_OK|10.0.2.15|DnsServers|1', timeout=20)
start = navigate(fixture.address)
ready = wait_body('External ready ' + nonce + ' classic,defer', start)
wait_body('Dynamic loaded ' + nonce, start)
checks.append('native HTTP external CSS and ordered classic/defer/dynamic JavaScript')
evidence['ExternalReadyBody'] = ready
move(window['X'] + window['Width'] - 20, window['Y'] + 50)
frame = capture('Browser-Pipeline-Css')
vx, vy, _, _ = viewport
color_pixels = count_color(frame, (vx + 30, vy + 30, 148, 52), (0x18, 0x77, 0xC9))
border_pixels = count_color(frame, (vx + 25, vy + 25, 158, 2), (0x75, 0xC9, 0xF5))
outside_pixels = count_color(frame, (vx + 188, vy + 30, 10, 30), (0xF1, 0xF6, 0xFB))
assert color_pixels > 148 * 52 * scale * scale * .95, ('CSS fill geometry/color', color_pixels)
assert border_pixels > 158 * 2 * scale * scale * .8, ('CSS border geometry/color', border_pixels)
assert outside_pixels > 10 * 30 * scale * scale * .95, ('CSS width extends beyond declared border-box', outside_pixels)
evidence['CssPixels'] = {'Fill': color_pixels, 'Border': border_pixels, 'Outside': outside_pixels}
checks.append('native framebuffer external CSS box geometry, fill and border colors')
start = len(text()); click(vx + 90, vy + 124)
wait_body('Button clicked ' + nonce, start)
capture('Browser-Pipeline-Click')
checks.append('native mouse hit-test and DOM click listener mutate visible content')
start = len(text()); click(vx + 65, vy + 180)
typed = 'xfenativeinput'
type_text(typed); wait_body('Input typed ' + typed + ' ' + nonce, start)
input_frame = capture('Browser-Pipeline-Input')
ink = count_color(input_frame, (vx + 30, vy + 166, 270, 24), (0x16, 0x26, 0x38), 10)
assert ink > 12 * scale * scale, ('textarea current value has no native text ink', ink)
evidence['TypedValue'] = typed; evidence['InputInkPixels'] = ink
checks.append('native keyboard beforeinput/input events and current textarea value paint')
wait_body('Timer fired ' + nonce, start=0)
wait_body('Animation frame ' + nonce, start=0)
checks.append('guest monotonic timer and requestAnimationFrame callbacks update DOM')
start = navigate('about:Monaco')
ready = wait_body('Official Monaco 0.52.2 - ready', start, 90)
# A theme-colored antialiased pointer can resemble a syntax color.
# Keep it on the address toolbar, outside every code band, before capture.
pointer_away = (window['X'] + window['Width'] - 20, window['Y'] + 50)
move(*pointer_away)
evidence['MonacoPointerExcluded'] = {'LogicalPosition': list(pointer_away), 'OutsideCodeBands': True}
# Editor construction precedes its first RAF text render. Wait for
# actual pixels rather than treating the model-ready string as paint.
paint_deadline = time.monotonic() + 60
paint_attempt = 0
while True:
paint_attempt += 1
frame = capture('Browser-OfficialMonaco-Ready-' + str(paint_attempt))
ready_paint = _monaco_frame_stats(frame, viewport, scale)
evidence['MonacoReadyPaint'] = {'Attempts': paint_attempt, **ready_paint}
if ready_paint['ReadyPainted'] or time.monotonic() >= paint_deadline: break
assert all(marker not in text() for marker in ('CPU EXCEPTION:', '[FAILFAST]', '*** UNHANDLED EXCEPTION')), text()[-4000:]
time.sleep(.25)
model_matches = list(MODEL.finditer(text()[start:]))
assert model_matches, 'Ready marker without actual Monaco model diagnostic'
original = model_matches[-1].group(1).replace('\r', '')
assert 'const answer = 6 * 7;' in original and 'console.log(answer);' in original, original
assert ready_paint['ReadyPainted'], ('Monaco model ready without three native code glyph lines and their syntax-color distribution', ready_paint)
token_pixels = sum(line['BlueSyntaxPixels'] for line in ready_paint['Lines'][:3])
evidence['MonacoReadyBody'] = ready; evidence['MonacoInitialValue'] = original; evidence['MonacoSyntaxPixels'] = token_pixels
checks.append('official packaged Monaco 0.52.2 initializes actual model and three native glyph lines with comment/keyword syntax-color distribution outside the pointer')
ready_frame = frame
start = len(text()); click(vx + 160, vy + 70)
chord('ctrl', 'end'); tap('ret')
marker = 'xfenativeedit'
type_text(marker)
wait_body('Monaco - edited', start, 30)
deadline = time.monotonic() + 20
edited = ''
while time.monotonic() < deadline:
models = list(MODEL.finditer(text()[start:]))
if models:
edited = models[-1].group(1).replace('\r', '')
if marker in edited: break
time.sleep(.05)
assert marker in edited and edited != original, ('Native typing did not update real Monaco getValue()', edited)
assert edited == original + '\n' + marker, ('Native input was lost, duplicated or inserted at the wrong position', edited)
original_lines, edited_lines = original.split('\n'), edited.split('\n')
assert len(original_lines) == 3 and len(edited_lines) >= 4 and edited_lines[:3] == original_lines and marker in edited_lines[3], \
('Native Ctrl+End/newline typing did not produce the expected real fourth model line', edited)
evidence['MonacoEditedValue'] = edited
checks.append('native mouse/keyboard edits official Monaco model confirmed by actual getValue')
move(*pointer_away)
paint_deadline = time.monotonic() + 60
edit_attempt = 0
while True:
edit_attempt += 1
edited_frame = capture('Browser-OfficialMonaco-Edited-' + str(edit_attempt))
edited_paint = _monaco_frame_stats(edited_frame, viewport, scale)
delta = _monaco_fourth_line_delta(ready_frame, edited_frame, edited_paint['Lines'][3]['NativeBounds'])
visible = edited_paint['ReadyPainted'] and edited_paint['Lines'][3]['HasTextGlyphDistribution'] \
and delta['NewInkPixels'] >= 35 * scale * scale and delta['NewInkColumns'] >= 24 * scale
evidence['MonacoEditedPaint'] = {'Attempts': edit_attempt, **edited_paint, 'FourthLineDelta': delta, 'FourthModelLine': edited_lines[3], 'Passed': visible}
if visible or time.monotonic() >= paint_deadline: break
assert all(marker not in text() for marker in ('CPU EXCEPTION:', '[FAILFAST]', '*** UNHANDLED EXCEPTION')), text()[-4000:]
time.sleep(.25)
assert visible, ('Real Monaco model changed but its native fourth-line text ink did not appear', evidence['MonacoEditedPaint'])
capture('Browser-OfficialMonaco-Edited') # Keep the established final artifact name as well as every waited frame.
checks.append('native fourth-line text glyphs and new ink agree with the real edited Monaco model after RAF paint')
# A real page button selects the actual C# model. Host probes and
# generated palette files never stand in for this guest interaction.
palette = website_palette()
csharp = {'Kind': 'ActualNativeMonacoWebsiteCSharp', 'Passed': False,
'WebsiteAssetManifestSha256': palette['AssetManifestSha256'],
'WebsiteCssSha256': palette['CssSha256'], 'MemoryProfile': 'Caller records the actual QEMU memory setting',
'Input': 'QMP physical mouse/keyboard events; no injected guest JavaScript or synthetic model',
'Boundary': 'Website grammar/CSS foreground parity; no Roslyn, C# execution, workers or pixel-identical font claim.'}
evidence['MonacoCSharp'] = csharp
def wait_csharp(start, marker=None, timeout=90):
deadline = time.monotonic() + timeout
last_error = 'No complete native C# DOM readback appeared'
while time.monotonic() < deadline:
for match in reversed(list(CSHARP_PROOF.finditer(text()[start:]))):
try:
actual = json.loads(match.group(1))
if actual.get('Language') != 'csharp':
continue
if marker is not None and marker not in actual.get('ModelValue', ''):
continue
verified = verify_readback(actual, palette)
return actual, verified
except (AssertionError, KeyError, TypeError, ValueError) as error:
last_error = str(error)
# Report the newest matching guest state. Rechecking an
# older pre-RAF snapshot would overwrite this diagnostic
# with an obsolete text mismatch and hide the real
# remaining token-color failure.
break
assert all(item not in text() for item in ('CPU EXCEPTION:', '[FAILFAST]', '*** UNHANDLED EXCEPTION')), text()[-4000:]
time.sleep(.1)
raise AssertionError('Actual native C# model/span color readback did not stabilize: ' + last_error)
def wait_csharp_input(start, expected_model, line_number, column, action, timeout=30):
"""Observe actual textarea focus/cursor/model after physical input.
No key is resent, no focus API is called and no model is injected.
A lost or misplaced character is a failure at its exact stage.
"""
deadline = time.monotonic() + timeout
last = None
while time.monotonic() < deadline:
matches = list(CSHARP_PROOF.finditer(text()[start:]))
if matches:
last = json.loads(matches[-1].group(1))
position = last.get('CursorPosition') or {}
if (last.get('Language') == 'csharp' and last.get('ModelValue') == expected_model and
last.get('EditorHasTextFocus') is True and last.get('ActiveElementTag') == 'TEXTAREA' and
'inputarea' in (last.get('ActiveElementClasses') or '').split() and
position.get('LineNumber') == line_number and position.get('Column') == column):
acknowledgement = {key:last.get(key) for key in ('Language','ModelValue','ModelVersionId','ActiveElementTag',
'ActiveElementClasses','ActiveElementId','EditorHasTextFocus','EditorHasWidgetFocus','CursorPosition','Selection')}
acknowledgement.update(Action=action,SerialOffset=start+matches[-1].start())
csharp.setdefault('NativeInputAcknowledgements',[]).append(acknowledgement)
return last
assert all(item not in text() for item in ('CPU EXCEPTION:', '[FAILFAST]', '*** UNHANDLED EXCEPTION')), text()[-4000:]
time.sleep(.05)
raise AssertionError(('Physical native C# input was not acknowledged', action,
{'ModelValue':expected_model,'LineNumber':line_number,'Column':column},last))
def wait_csharp_focus(start, expected_model, timeout=30):
deadline = time.monotonic() + timeout
last = None
while time.monotonic() < deadline:
matches = list(CSHARP_PROOF.finditer(text()[start:]))
if matches:
last = json.loads(matches[-1].group(1))
if (last.get('Language') == 'csharp' and last.get('ModelValue') == expected_model and
last.get('EditorHasTextFocus') is True and last.get('ActiveElementTag') == 'TEXTAREA' and
'inputarea' in (last.get('ActiveElementClasses') or '').split()):
csharp['PhysicalClickFocusAcknowledgement'] = {key:last.get(key) for key in ('ActiveElementTag',
'ActiveElementClasses','ActiveElementId','EditorHasTextFocus','EditorHasWidgetFocus','CursorPosition','ModelVersionId')}
csharp['PhysicalClickFocusAcknowledgement']['SerialOffset'] = start+matches[-1].start()
return last
assert all(item not in text() for item in ('CPU EXCEPTION:', '[FAILFAST]', '*** UNHANDLED EXCEPTION')), text()[-4000:]
time.sleep(.05)
raise AssertionError(('Physical C# editor click did not focus the actual Monaco textarea',last))
csharp_start = len(text())
click(vx + viewport[2] - 20, vy + 14)
csharp['LanguageButtonCssPosition'] = [vx + viewport[2] - 20, vy + 14]
wait_body('Monaco C# - website grammar and palette', csharp_start, 90)
actual, verified = wait_csharp(csharp_start)
csharp_original = actual['ModelValue']
assert csharp_original.startswith('using System;\nnamespace XFEstudio;') and 'public sealed class Preview' in csharp_original, csharp_original
assert 'Math.Max(value, 42)' in csharp_original and 'Console.WriteLine("Ready")' in csharp_original
csharp['InitialModelValue'] = csharp_original
csharp['InitialDomReadback'] = actual
csharp['InitialSpanColorParity'] = verified
checks.append('real native C# language button selects the official Monaco model with website highlight.js token classification')
checks.append('every actual native C# rendered span foreground agrees with the unchanged website CSS palette and token scopes')
move(*pointer_away)
paint_deadline = time.monotonic() + 60
attempt = 0
while True:
attempt += 1
csharp_frame = capture('Browser-OfficialMonaco-CSharp-Ready-' + str(attempt))
painted = csharp_frame_stats(csharp_frame, viewport, scale, csharp_original)
csharp['InitialFramebuffer'] = {'Attempts': attempt, **painted}
if painted['Passed'] or time.monotonic() >= paint_deadline:
break
assert all(item not in text() for item in ('CPU EXCEPTION:', '[FAILFAST]', '*** UNHANDLED EXCEPTION')), text()[-4000:]
time.sleep(.25)
assert painted['Passed'], ('Actual C# DOM colors were correct but the real native framebuffer did not paint the C# source and all website categories', painted)
capture('Browser-OfficialMonaco-CSharp-Ready')
checks.append('native C# framebuffer shows actual model lines and website keyword/type/control-flow/string/number foreground ink outside pointer and UI')
csharp_edit_start = len(text())
move(vx + 160, vy + 70)
hold_started = time.monotonic()
hold_evidence = {'BrowserCssPosition':[160,70],'DesktopCssPosition':[vx+160,vy+70],
'NativePixelPosition':[round((vx+160)*scale),round((vy+70)*scale)],
'MouseDownSerialOffset':len(text()),'MouseDownSent':False,'MouseUpSent':False,
'FocusAcknowledged':False,'Retries':0,'FocusOrModelInjected':False}
csharp['HoldUntilActualGuestFocus'] = hold_evidence
qmp('input-send-event',{'events':[{'type':'btn','data':{'down':True,'button':'left'}}]})
hold_evidence['MouseDownSent'] = True
try:
focus_actual = wait_csharp_focus(hold_evidence['MouseDownSerialOffset'],csharp_original)
hold_evidence['FocusAcknowledged'] = True
hold_evidence['FocusedCursorPosition'] = focus_actual['CursorPosition']
hold_evidence['UnchangedModelLength'] = focus_actual['ModelLength']
actual_mousedowns = re.findall(r'XFE_BROWSER_INPUT\|mousedown\|160\|70\|[^\r\n]*',text()[hold_evidence['MouseDownSerialOffset']:])
assert actual_mousedowns, 'Physical C# mouse-down did not reach the actual editor body'
hold_evidence['ActualBodyMouseDownTrace'] = actual_mousedowns[-1]
finally:
# Always release the real device on a failed focus assertion too.
# Holding until observed focus is not a repeated click or JS focus.
release_start = len(text())
qmp('input-send-event',{'events':[{'type':'btn','data':{'down':False,'button':'left'}}]})
hold_evidence['MouseUpSent'] = True
hold_evidence['MouseUpSerialOffset'] = release_start
hold_evidence['HeldHostSeconds'] = time.monotonic()-hold_started
wait_log('XFE_BROWSER_INPUT|mouseup|160|70|',release_start,30)
actual_mouseups = re.findall(r'XFE_BROWSER_INPUT\|mouseup\|160\|70\|[^\r\n]*',text()[release_start:])
assert actual_mouseups, 'Physical C# mouse-up was not routed to the actual editor body'
hold_evidence['ActualBodyMouseUpTrace'] = actual_mouseups[-1]
native_transitions = re.findall(r'XFE_NATIVE_POINTER\|[^\r\n]*',text()[hold_evidence['MouseDownSerialOffset']:])
hold_evidence['ActualNativePointerTransitions'] = native_transitions
end_start = len(text());chord('ctrl', 'end')
original_lines = csharp_original.split('\n')
wait_csharp_input(end_start,csharp_original,len(original_lines),len(original_lines[-1])+1,'Ctrl+End reaches actual model end')
enter_start = len(text());tap('ret')
wait_csharp_input(enter_start,csharp_original+'\n',len(original_lines)+1,1,'Enter creates actual final model line')
csharp_marker = '// xfenativecsharp'
for index, character in enumerate(csharp_marker):
character_start = len(text());type_text(character)
wait_csharp_input(character_start,csharp_original+'\n'+csharp_marker[:index+1],len(original_lines)+1,index+2,
'Physical C# character '+str(index+1)+' '+repr(character))
wait_body('Monaco - edited', csharp_edit_start, 30)
edited_actual, edited_verified = wait_csharp(csharp_edit_start, csharp_marker)
assert edited_actual['ModelValue'] == csharp_original + '\n' + csharp_marker, ('C# native model input was lost, duplicated or inserted at an unexpected position', edited_actual['ModelValue'])
csharp['EditedModelValue'] = edited_actual['ModelValue']
csharp['EditedDomReadback'] = edited_actual
csharp['EditedSpanColorParity'] = edited_verified
move(*pointer_away)
paint_deadline = time.monotonic() + 60
attempt = 0
while True:
attempt += 1
edited_csharp_frame = capture('Browser-OfficialMonaco-CSharp-Edited-' + str(attempt))
edited_csharp_paint = csharp_frame_stats(edited_csharp_frame, viewport, scale, edited_actual['ModelValue'], require_comment=True)
csharp['EditedFramebuffer'] = {'Attempts': attempt, **edited_csharp_paint}
if edited_csharp_paint['Passed'] or time.monotonic() >= paint_deadline:
break
assert all(item not in text() for item in ('CPU EXCEPTION:', '[FAILFAST]', '*** UNHANDLED EXCEPTION')), text()[-4000:]
time.sleep(.25)
assert edited_csharp_paint['Passed'], ('Edited C# actual model/newline/comment did not paint with the website comment color', edited_csharp_paint)
capture('Browser-OfficialMonaco-CSharp-Edited')
csharp['Passed'] = True
checks.append('physical native C# typing appends a real new model line and repaints every span with website colors including the new comment')
requested = [urlsplit(item['Path']).path for item in fixture.requests]
for expected in ('/Index', '/External.css', '/Classic.js', '/Defer.js', '/Dynamic.js'):
assert expected in requested, ('missing native peer request', expected, requested)
evidence['FixtureNonce'] = nonce; evidence['FixtureAddress'] = fixture.address
evidence['FixtureRequests'] = fixture.requests.copy()
evidence['FixtureResourcesSha256'] = {path: hashlib.sha256(source.encode('utf-8')).hexdigest() for path, (_, source) in fixture.resources.items()}
evidence['Passed'] = True
return evidence
except Exception as error:
evidence['Failure'] = str(error)
raise
finally:
fixture.close()
if output is not None:
(output / 'BrowserPipelinePeer.json').write_text(json.dumps({'Nonce': nonce, 'Address': fixture.address, 'Requests': fixture.requests}, ensure_ascii=False, indent=2), encoding='utf-8')
evidence['FixtureNonce'] = nonce; evidence['FixtureAddress'] = fixture.address; evidence['FixtureRequests'] = fixture.requests.copy()
evidence['FixtureResourcesSha256'] = {path: hashlib.sha256(source.encode('utf-8')).hexdigest() for path, (_, source) in fixture.resources.items()}
# The on-disk receipt also survives an assertion failure, including
# all original screenshot hashes and the final native paint measurements.
receipt_path = output / 'BrowserPipelineEvidence.json'
receipt_path.write_text(json.dumps(evidence, ensure_ascii=False, indent=2), encoding='utf-8')
evidence['EvidencePath'] = str(receipt_path)
evidence['EvidenceSha256'] = hashlib.sha256(receipt_path.read_bytes()).hexdigest()
"""CSS / external JavaScript / events / actual Monaco checks in a private QEMU.
The HTTP peer supplies controlled bytes over the guest's native NIC. QMP only
sends real keyboard/mouse input and captures the native framebuffer. No browser
state is injected through a host browser, guest debugger or synthetic DOM.
"""
import hashlib
import html
import json
import pathlib
import re
import threading
import time
import uuid
from datetime import datetime, timezone
from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer
from urllib.parse import urlsplit
from PIL import Image
from NativeCSharpEvidence import CSHARP_PROOF, csharp_frame_stats, verify_readback, website_palette
WINDOW = re.compile(r'^XFE_WINDOW_STATE\|(\d+)\|Browser\|(-?\d+)\|(-?\d+)\|(\d+)\|(\d+)\|([01])\|([01])\|([01])$', re.M)
PAGE = re.compile(r'XFE_BROWSER_STATE_BEGIN\r?\n([^\n]*)\n(.*?)\r?\nXFE_BROWSER_STATE_END', re.S)
MODEL = re.compile(r'XFE_MONACO_VALUE_BEGIN\r?\n(.*?)\r?\nXFE_MONACO_VALUE_END', re.S)
class BrowserFixture:
"""Loopback-only fixture with request evidence and deterministic resources."""
def __init__(self, nonce):
self.nonce = nonce
self.requests = []
self.lock = threading.Lock()
quoted = json.dumps(nonce)
self.resources = {
'/External.css': ('text/css', '''html,body{margin:0;padding:0;background:#F1F6FB;color:#162638;font-family:monospace;font-size:16px}
#Swatch{position:absolute;left:24px;top:24px;width:160px;height:64px;box-sizing:border-box;border:4px solid #75C9F5;background:#1877C9}
#Click{position:absolute;left:24px;top:104px;width:200px;height:40px;box-sizing:border-box;background:#4086B8;color:white;border:2px solid #75C9F5}
#Input{position:absolute;left:24px;top:160px;width:300px;height:60px;box-sizing:border-box;background:white;color:#162638;border:2px solid #4086B8;padding:4px}
#Outputs{position:absolute;left:360px;top:24px;width:400px;font-size:13px;line-height:20px}'''),
'/Classic.js': ('application/javascript', "window.fixtureOrder=['classic'];"),
'/Defer.js': ('application/javascript', '''window.fixtureOrder.push('defer');
document.getElementById('Ready').textContent='External ready '+NONCE+' '+fixtureOrder.join(',');
document.getElementById('Click').addEventListener('click',function(){document.getElementById('ClickResult').textContent='Button clicked '+NONCE;});
document.getElementById('Input').addEventListener('input',function(){document.getElementById('InputResult').textContent='Input typed '+this.value+' '+NONCE;});
setTimeout(function(){document.getElementById('Timer').textContent='Timer fired '+NONCE;},1200);
requestAnimationFrame(function(){document.getElementById('Frame').textContent='Animation frame '+NONCE;});
var external=document.createElement('script');external.src='/Dynamic.js';document.head.appendChild(external);'''.replace('NONCE', quoted)),
'/Dynamic.js': ('application/javascript', "window.fixtureOrder.push('dynamic');document.getElementById('Dynamic').textContent='Dynamic loaded '+" + quoted + ";"),
}
document = '''<!doctype html><html><head><title>XFE pipeline</title>
<link rel=stylesheet href=/External.css><script src=/Classic.js></script><script defer src=/Defer.js></script></head>
<body><div id=Swatch></div><button id=Click>Click native event</button><textarea id=Input></textarea>
<div id=Outputs><div id=Ready>External pending</div><div id=Dynamic>Dynamic pending</div><div id=ClickResult>Click pending</div>
<div id=InputResult>Input pending</div><div id=Timer>Timer pending</div><div id=Frame>Frame pending</div><div>NONCE</div></div></body></html>'''
self.resources['/Index'] = ('text/html', document.replace('NONCE', html.escape(nonce)))
fixture = self
class Handler(BaseHTTPRequestHandler):
protocol_version = 'HTTP/1.1'
def log_message(self, *_):
pass
def do_GET(self):
path = urlsplit(self.path).path
with fixture.lock:
fixture.requests.append({'Path': self.path, 'Utc': datetime.now(timezone.utc).isoformat(),
'Host': self.headers.get('Host'), 'Peer': self.client_address[0]})
self.close_connection = True
resource = fixture.resources.get(path)
if resource is None:
self.send_error(404)
return
content_type, source = resource
body = source.encode('utf-8')
try:
self.send_response(200)
self.send_header('Content-Type', content_type + '; charset=utf-8')
self.send_header('Content-Length', str(len(body)))
self.send_header('Connection', 'close')
self.end_headers()
self.wfile.write(body)
self.wfile.flush()
except (BrokenPipeError, ConnectionResetError):
pass
self.server = ThreadingHTTPServer(('127.0.0.1', 0), Handler)
self.server.daemon_threads = True
self.thread = threading.Thread(target=self.server.serve_forever, kwargs={'poll_interval': .1}, daemon=True)
self.thread.start()
@property
def address(self):
return f'http://10.0.2.2:{self.server.server_port}/Index'
def close(self):
self.server.shutdown()
self.server.server_close()
self.thread.join(timeout=2)
def _monaco_frame_stats(frame, viewport, scale):
"""Measure real glyph ink in the controlled page's configured 20px lines.
This does not synthesize or OCR code. The actual getValue assertion verifies
text; these independent pixel bands verify its multi-line native paint.
The header, gutter and pointer are kept outside this region by the caller.
"""
vx, vy, width, _ = viewport
lines = []
for index in range(4):
x, y, w, h = vx + 42, vy + 28 + index * 20, min(600, width - 42), 20
native = (round(x * scale), round(y * scale), round((x + w) * scale), round((y + h) * scale))
crop = frame.crop(native).convert('RGB')
columns, rows = set(), set()
ink = blue = green = 0
for row in range(crop.height):
for column in range(crop.width):
pixel = crop.getpixel((column, row))
# The editor's dark background/current-line borders are below
# this threshold; syntax colors and foreground glyphs exceed it.
if .2126 * pixel[0] + .7152 * pixel[1] + .0722 * pixel[2] >= 78:
ink += 1; columns.add(column); rows.add(row)
if all(abs(pixel[channel] - (0x56, 0x9C, 0xD6)[channel]) <= 12 for channel in range(3)):
blue += 1
if any(all(abs(pixel[channel] - color[channel]) <= 12 for channel in range(3)) for color in ((0x60, 0x8B, 0x4E), (0x6A, 0x99, 0x55))):
green += 1
span = max(columns) - min(columns) + 1 if columns else 0
glyphs = ink >= 35 * scale * scale and len(columns) >= 24 * scale and len(rows) >= 4 * scale and span >= 40 * scale
lines.append({'Line': index + 1, 'CssBounds': [x, y, w, h], 'NativeBounds': list(native),
'InkPixels': ink, 'InkColumns': len(columns), 'InkRows': len(rows), 'InkSpan': span,
'BlueSyntaxPixels': blue, 'GreenCommentPixels': green, 'HasTextGlyphDistribution': glyphs})
return {'ConfiguredLineHeightCss': 20, 'EditorHeaderHeightCss': 28, 'Lines': lines,
'ReadyPainted': all(line['HasTextGlyphDistribution'] for line in lines[:3])
and lines[0]['GreenCommentPixels'] >= 8 * scale * scale
and lines[1]['BlueSyntaxPixels'] >= 8 * scale * scale}
def _monaco_fourth_line_delta(before, after, native_bounds):
"""New text ink only: changing a dark selection/current-line fill is insufficient."""
old = before.crop(native_bounds).convert('RGB'); new = after.crop(native_bounds).convert('RGB')
added = set(); pixels = 0
for row in range(new.height):
for column in range(new.width):
old_pixel = old.getpixel((column, row)); pixel = new.getpixel((column, row))
old_ink = .2126 * old_pixel[0] + .7152 * old_pixel[1] + .0722 * old_pixel[2] >= 78
new_ink = .2126 * pixel[0] + .7152 * pixel[1] + .0722 * pixel[2] >= 78
if new_ink and not old_ink:
pixels += 1; added.add(column)
return {'NewInkPixels': pixels, 'NewInkColumns': len(added)}
def run_browser_checks(qmp, text, wait_log, screenshot, native_width, native_height, scale, pointer):
checks = []
evidence = {'Kind': 'NativeBrowserPipeline', 'NativeWidth': native_width, 'NativeHeight': native_height,
'Scale': scale, 'Checks': checks, 'Passed': False,
'Boundary': 'Original bounded CSS layout and classic-script interpreter; no full Chromium, complete CSS, workers, GPU canvas or verified HTTPS claim.'}
nonce = 'Guest-' + uuid.uuid4().hex[:12]
fixture = BrowserFixture(nonce)
output = None
def key(code, down):
qmp('input-send-event', {'events': [{'type': 'key', 'data': {'down': down, 'key': {'type': 'qcode', 'data': code}}}]})
time.sleep(.025)
def tap(code):
key(code, True); key(code, False)
def chord(modifier, code):
key(modifier, True); tap(code); key(modifier, False)
def type_text(value):
simple = {'.': 'dot', '/': 'slash', '-': 'minus', ' ': 'spc', '\n': 'ret'}
shifted = {':': 'semicolon', '_': 'minus', '?': 'slash'}
for character in value:
if character in shifted: chord('shift', shifted[character])
elif character.isupper(): chord('shift', character.lower())
else: tap(simple.get(character, character))
def move(x, y):
target = [round(x * scale), round(y * scale)]
while pointer != target:
dx = max(-80, min(80, target[0] - pointer[0])); dy = max(-80, min(80, target[1] - pointer[1]))
qmp('input-send-event', {'events': [{'type': 'rel', 'data': {'axis': 'x', 'value': dx}}, {'type': 'rel', 'data': {'axis': 'y', 'value': dy}}]})
pointer[0] += dx; pointer[1] += dy
time.sleep(.018)
def click(x, y):
move(x, y)
for down in (True, False):
qmp('input-send-event', {'events': [{'type': 'btn', 'data': {'down': down, 'button': 'left'}}]})
time.sleep(.08)
def capture(name):
nonlocal output
time.sleep(.15)
path = pathlib.Path(screenshot(name)).resolve()
output = path.parent
with Image.open(path) as saved:
assert saved.size == (native_width, native_height), saved.size
frame = saved.convert('RGB').copy()
evidence.setdefault('Screenshots', []).append({'Path': str(path), 'Sha256': hashlib.sha256(path.read_bytes()).hexdigest()})
return frame
def page_bodies(start):
return [match.group(2).replace('\r', '') for match in PAGE.finditer(text()[start:])]
def wait_body(marker, start, timeout=20):
deadline = time.monotonic() + timeout
while time.monotonic() < deadline:
bodies = page_bodies(start)
for body in reversed(bodies):
if marker in body: return body
log = text()
assert '[FAILFAST]' not in log and '*** UNHANDLED EXCEPTION' not in log and 'CPU EXCEPTION:' not in log, log[-4000:]
time.sleep(.05)
raise AssertionError('Native browser state timeout: ' + marker + '\n' + text()[start:][-7000:])
def navigate(address):
start = len(text()); chord('ctrl', 'l'); type_text(address); tap('ret')
wait_log('XFE_BROWSER_NAVIGATED|', start, 30)
return start
def browser_bounds(start):
deadline = time.monotonic() + 10
while time.monotonic() < deadline:
matches = list(WINDOW.finditer(text()[start:]))
if matches:
parts = matches[-1].groups()
return {'Id': int(parts[0]), 'X': int(parts[1]), 'Y': int(parts[2]), 'Width': int(parts[3]), 'Height': int(parts[4])}
time.sleep(.05)
raise AssertionError('Browser window geometry log missing')
def count_color(frame, bounds, rgb, tolerance=3):
x, y, width, height = bounds
crop = frame.crop((round(x * scale), round(y * scale), round((x + width) * scale), round((y + height) * scale)))
return sum(all(abs(pixel[channel] - rgb[channel]) <= tolerance for channel in range(3)) for pixel in crop.getdata())
try:
start = len(text()); click(60, 308)
wait_log('XFE_DESKTOP_ACTIVE|Browser', start)
window = browser_bounds(start)
viewport = (window['X'] + 2, window['Y'] + 67, window['Width'] - 4, window['Height'] - 96)
evidence['BrowserWindow'] = window; evidence['BrowserViewport'] = viewport
capture('Browser-Pipeline-Start') # Establish the private evidence directory even if a later request fails.
wait_log('XFE_NETWORK_DHCP_OK|10.0.2.15|DnsServers|1', timeout=20)
start = navigate(fixture.address)
ready = wait_body('External ready ' + nonce + ' classic,defer', start)
wait_body('Dynamic loaded ' + nonce, start)
checks.append('native HTTP external CSS and ordered classic/defer/dynamic JavaScript')
evidence['ExternalReadyBody'] = ready
move(window['X'] + window['Width'] - 20, window['Y'] + 50)
frame = capture('Browser-Pipeline-Css')
vx, vy, _, _ = viewport
color_pixels = count_color(frame, (vx + 30, vy + 30, 148, 52), (0x18, 0x77, 0xC9))
border_pixels = count_color(frame, (vx + 25, vy + 25, 158, 2), (0x75, 0xC9, 0xF5))
outside_pixels = count_color(frame, (vx + 188, vy + 30, 10, 30), (0xF1, 0xF6, 0xFB))
assert color_pixels > 148 * 52 * scale * scale * .95, ('CSS fill geometry/color', color_pixels)
assert border_pixels > 158 * 2 * scale * scale * .8, ('CSS border geometry/color', border_pixels)
assert outside_pixels > 10 * 30 * scale * scale * .95, ('CSS width extends beyond declared border-box', outside_pixels)
evidence['CssPixels'] = {'Fill': color_pixels, 'Border': border_pixels, 'Outside': outside_pixels}
checks.append('native framebuffer external CSS box geometry, fill and border colors')
start = len(text()); click(vx + 90, vy + 124)
wait_body('Button clicked ' + nonce, start)
capture('Browser-Pipeline-Click')
checks.append('native mouse hit-test and DOM click listener mutate visible content')
start = len(text()); click(vx + 65, vy + 180)
typed = 'xfenativeinput'
type_text(typed); wait_body('Input typed ' + typed + ' ' + nonce, start)
input_frame = capture('Browser-Pipeline-Input')
ink = count_color(input_frame, (vx + 30, vy + 166, 270, 24), (0x16, 0x26, 0x38), 10)
assert ink > 12 * scale * scale, ('textarea current value has no native text ink', ink)
evidence['TypedValue'] = typed; evidence['InputInkPixels'] = ink
checks.append('native keyboard beforeinput/input events and current textarea value paint')
wait_body('Timer fired ' + nonce, start=0)
wait_body('Animation frame ' + nonce, start=0)
checks.append('guest monotonic timer and requestAnimationFrame callbacks update DOM')
start = navigate('about:Monaco')
ready = wait_body('Official Monaco 0.52.2 - ready', start, 90)
# A theme-colored antialiased pointer can resemble a syntax color.
# Keep it on the address toolbar, outside every code band, before capture.
pointer_away = (window['X'] + window['Width'] - 20, window['Y'] + 50)
move(*pointer_away)
evidence['MonacoPointerExcluded'] = {'LogicalPosition': list(pointer_away), 'OutsideCodeBands': True}
# Editor construction precedes its first RAF text render. Wait for
# actual pixels rather than treating the model-ready string as paint.
paint_deadline = time.monotonic() + 60
paint_attempt = 0
while True:
paint_attempt += 1
frame = capture('Browser-OfficialMonaco-Ready-' + str(paint_attempt))
ready_paint = _monaco_frame_stats(frame, viewport, scale)
evidence['MonacoReadyPaint'] = {'Attempts': paint_attempt, **ready_paint}
if ready_paint['ReadyPainted'] or time.monotonic() >= paint_deadline: break
assert all(marker not in text() for marker in ('CPU EXCEPTION:', '[FAILFAST]', '*** UNHANDLED EXCEPTION')), text()[-4000:]
time.sleep(.25)
model_matches = list(MODEL.finditer(text()[start:]))
assert model_matches, 'Ready marker without actual Monaco model diagnostic'
original = model_matches[-1].group(1).replace('\r', '')
assert 'const answer = 6 * 7;' in original and 'console.log(answer);' in original, original
assert ready_paint['ReadyPainted'], ('Monaco model ready without three native code glyph lines and their syntax-color distribution', ready_paint)
token_pixels = sum(line['BlueSyntaxPixels'] for line in ready_paint['Lines'][:3])
evidence['MonacoReadyBody'] = ready; evidence['MonacoInitialValue'] = original; evidence['MonacoSyntaxPixels'] = token_pixels
checks.append('official packaged Monaco 0.52.2 initializes actual model and three native glyph lines with comment/keyword syntax-color distribution outside the pointer')
ready_frame = frame
start = len(text()); click(vx + 160, vy + 70)
chord('ctrl', 'end'); tap('ret')
marker = 'xfenativeedit'
type_text(marker)
wait_body('Monaco - edited', start, 30)
deadline = time.monotonic() + 20
edited = ''
while time.monotonic() < deadline:
models = list(MODEL.finditer(text()[start:]))
if models:
edited = models[-1].group(1).replace('\r', '')
if marker in edited: break
time.sleep(.05)
assert marker in edited and edited != original, ('Native typing did not update real Monaco getValue()', edited)
assert edited == original + '\n' + marker, ('Native input was lost, duplicated or inserted at the wrong position', edited)
original_lines, edited_lines = original.split('\n'), edited.split('\n')
assert len(original_lines) == 3 and len(edited_lines) >= 4 and edited_lines[:3] == original_lines and marker in edited_lines[3], \
('Native Ctrl+End/newline typing did not produce the expected real fourth model line', edited)
evidence['MonacoEditedValue'] = edited
checks.append('native mouse/keyboard edits official Monaco model confirmed by actual getValue')
move(*pointer_away)
paint_deadline = time.monotonic() + 60
edit_attempt = 0
while True:
edit_attempt += 1
edited_frame = capture('Browser-OfficialMonaco-Edited-' + str(edit_attempt))
edited_paint = _monaco_frame_stats(edited_frame, viewport, scale)
delta = _monaco_fourth_line_delta(ready_frame, edited_frame, edited_paint['Lines'][3]['NativeBounds'])
visible = edited_paint['ReadyPainted'] and edited_paint['Lines'][3]['HasTextGlyphDistribution'] \
and delta['NewInkPixels'] >= 35 * scale * scale and delta['NewInkColumns'] >= 24 * scale
evidence['MonacoEditedPaint'] = {'Attempts': edit_attempt, **edited_paint, 'FourthLineDelta': delta, 'FourthModelLine': edited_lines[3], 'Passed': visible}
if visible or time.monotonic() >= paint_deadline: break
assert all(marker not in text() for marker in ('CPU EXCEPTION:', '[FAILFAST]', '*** UNHANDLED EXCEPTION')), text()[-4000:]
time.sleep(.25)
assert visible, ('Real Monaco model changed but its native fourth-line text ink did not appear', evidence['MonacoEditedPaint'])
capture('Browser-OfficialMonaco-Edited') # Keep the established final artifact name as well as every waited frame.
checks.append('native fourth-line text glyphs and new ink agree with the real edited Monaco model after RAF paint')
# A real page button selects the actual C# model. Host probes and
# generated palette files never stand in for this guest interaction.
palette = website_palette()
csharp = {'Kind': 'ActualNativeMonacoWebsiteCSharp', 'Passed': False,
'WebsiteAssetManifestSha256': palette['AssetManifestSha256'],
'WebsiteCssSha256': palette['CssSha256'], 'MemoryProfile': 'Caller records the actual QEMU memory setting',
'Input': 'QMP physical mouse/keyboard events; no injected guest JavaScript or synthetic model',
'Boundary': 'Website grammar/CSS foreground parity; no Roslyn, C# execution, workers or pixel-identical font claim.'}
evidence['MonacoCSharp'] = csharp
def wait_csharp(start, marker=None, timeout=90):
deadline = time.monotonic() + timeout
last_error = 'No complete native C# DOM readback appeared'
while time.monotonic() < deadline:
for match in reversed(list(CSHARP_PROOF.finditer(text()[start:]))):
try:
actual = json.loads(match.group(1))
if actual.get('Language') != 'csharp':
continue
if marker is not None and marker not in actual.get('ModelValue', ''):
continue
verified = verify_readback(actual, palette)
return actual, verified
except (AssertionError, KeyError, TypeError, ValueError) as error:
last_error = str(error)
# Report the newest matching guest state. Rechecking an
# older pre-RAF snapshot would overwrite this diagnostic
# with an obsolete text mismatch and hide the real
# remaining token-color failure.
break
assert all(item not in text() for item in ('CPU EXCEPTION:', '[FAILFAST]', '*** UNHANDLED EXCEPTION')), text()[-4000:]
time.sleep(.1)
raise AssertionError('Actual native C# model/span color readback did not stabilize: ' + last_error)
def wait_csharp_input(start, expected_model, line_number, column, action, timeout=30):
"""Observe actual textarea focus/cursor/model after physical input.
No key is resent, no focus API is called and no model is injected.
A lost or misplaced character is a failure at its exact stage.
"""
deadline = time.monotonic() + timeout
last = None
while time.monotonic() < deadline:
matches = list(CSHARP_PROOF.finditer(text()[start:]))
if matches:
last = json.loads(matches[-1].group(1))
position = last.get('CursorPosition') or {}
if (last.get('Language') == 'csharp' and last.get('ModelValue') == expected_model and
last.get('EditorHasTextFocus') is True and last.get('ActiveElementTag') == 'TEXTAREA' and
'inputarea' in (last.get('ActiveElementClasses') or '').split() and
position.get('LineNumber') == line_number and position.get('Column') == column):
acknowledgement = {key:last.get(key) for key in ('Language','ModelValue','ModelVersionId','ActiveElementTag',
'ActiveElementClasses','ActiveElementId','EditorHasTextFocus','EditorHasWidgetFocus','CursorPosition','Selection')}
acknowledgement.update(Action=action,SerialOffset=start+matches[-1].start())
csharp.setdefault('NativeInputAcknowledgements',[]).append(acknowledgement)
return last
assert all(item not in text() for item in ('CPU EXCEPTION:', '[FAILFAST]', '*** UNHANDLED EXCEPTION')), text()[-4000:]
time.sleep(.05)
raise AssertionError(('Physical native C# input was not acknowledged', action,
{'ModelValue':expected_model,'LineNumber':line_number,'Column':column},last))
def wait_csharp_focus(start, expected_model, timeout=30):
deadline = time.monotonic() + timeout
last = None
while time.monotonic() < deadline:
matches = list(CSHARP_PROOF.finditer(text()[start:]))
if matches:
last = json.loads(matches[-1].group(1))
if (last.get('Language') == 'csharp' and last.get('ModelValue') == expected_model and
last.get('EditorHasTextFocus') is True and last.get('ActiveElementTag') == 'TEXTAREA' and
'inputarea' in (last.get('ActiveElementClasses') or '').split()):
csharp['PhysicalClickFocusAcknowledgement'] = {key:last.get(key) for key in ('ActiveElementTag',
'ActiveElementClasses','ActiveElementId','EditorHasTextFocus','EditorHasWidgetFocus','CursorPosition','ModelVersionId')}
csharp['PhysicalClickFocusAcknowledgement']['SerialOffset'] = start+matches[-1].start()
return last
assert all(item not in text() for item in ('CPU EXCEPTION:', '[FAILFAST]', '*** UNHANDLED EXCEPTION')), text()[-4000:]
time.sleep(.05)
raise AssertionError(('Physical C# editor click did not focus the actual Monaco textarea',last))
csharp_start = len(text())
click(vx + viewport[2] - 20, vy + 14)
csharp['LanguageButtonCssPosition'] = [vx + viewport[2] - 20, vy + 14]
wait_body('Monaco C# - website grammar and palette', csharp_start, 90)
actual, verified = wait_csharp(csharp_start)
csharp_original = actual['ModelValue']
assert csharp_original.startswith('using System;\nnamespace XFEstudio;') and 'public sealed class Preview' in csharp_original, csharp_original
assert 'Math.Max(value, 42)' in csharp_original and 'Console.WriteLine("Ready")' in csharp_original
csharp['InitialModelValue'] = csharp_original
csharp['InitialDomReadback'] = actual
csharp['InitialSpanColorParity'] = verified
checks.append('real native C# language button selects the official Monaco model with website highlight.js token classification')
checks.append('every actual native C# rendered span foreground agrees with the unchanged website CSS palette and token scopes')
move(*pointer_away)
paint_deadline = time.monotonic() + 60
attempt = 0
while True:
attempt += 1
csharp_frame = capture('Browser-OfficialMonaco-CSharp-Ready-' + str(attempt))
painted = csharp_frame_stats(csharp_frame, viewport, scale, csharp_original)
csharp['InitialFramebuffer'] = {'Attempts': attempt, **painted}
if painted['Passed'] or time.monotonic() >= paint_deadline:
break
assert all(item not in text() for item in ('CPU EXCEPTION:', '[FAILFAST]', '*** UNHANDLED EXCEPTION')), text()[-4000:]
time.sleep(.25)
assert painted['Passed'], ('Actual C# DOM colors were correct but the real native framebuffer did not paint the C# source and all website categories', painted)
capture('Browser-OfficialMonaco-CSharp-Ready')
checks.append('native C# framebuffer shows actual model lines and website keyword/type/control-flow/string/number foreground ink outside pointer and UI')
csharp_edit_start = len(text())
move(vx + 160, vy + 70)
hold_started = time.monotonic()
hold_evidence = {'BrowserCssPosition':[160,70],'DesktopCssPosition':[vx+160,vy+70],
'NativePixelPosition':[round((vx+160)*scale),round((vy+70)*scale)],
'MouseDownSerialOffset':len(text()),'MouseDownSent':False,'MouseUpSent':False,
'FocusAcknowledged':False,'Retries':0,'FocusOrModelInjected':False}
csharp['HoldUntilActualGuestFocus'] = hold_evidence
qmp('input-send-event',{'events':[{'type':'btn','data':{'down':True,'button':'left'}}]})
hold_evidence['MouseDownSent'] = True
try:
focus_actual = wait_csharp_focus(hold_evidence['MouseDownSerialOffset'],csharp_original)
hold_evidence['FocusAcknowledged'] = True
hold_evidence['FocusedCursorPosition'] = focus_actual['CursorPosition']
hold_evidence['UnchangedModelLength'] = focus_actual['ModelLength']
actual_mousedowns = re.findall(r'XFE_BROWSER_INPUT\|mousedown\|160\|70\|[^\r\n]*',text()[hold_evidence['MouseDownSerialOffset']:])
assert actual_mousedowns, 'Physical C# mouse-down did not reach the actual editor body'
hold_evidence['ActualBodyMouseDownTrace'] = actual_mousedowns[-1]
finally:
# Always release the real device on a failed focus assertion too.
# Holding until observed focus is not a repeated click or JS focus.
release_start = len(text())
qmp('input-send-event',{'events':[{'type':'btn','data':{'down':False,'button':'left'}}]})
hold_evidence['MouseUpSent'] = True
hold_evidence['MouseUpSerialOffset'] = release_start
hold_evidence['HeldHostSeconds'] = time.monotonic()-hold_started
wait_log('XFE_BROWSER_INPUT|mouseup|160|70|',release_start,30)
actual_mouseups = re.findall(r'XFE_BROWSER_INPUT\|mouseup\|160\|70\|[^\r\n]*',text()[release_start:])
assert actual_mouseups, 'Physical C# mouse-up was not routed to the actual editor body'
hold_evidence['ActualBodyMouseUpTrace'] = actual_mouseups[-1]
native_transitions = re.findall(r'XFE_NATIVE_POINTER\|[^\r\n]*',text()[hold_evidence['MouseDownSerialOffset']:])
hold_evidence['ActualNativePointerTransitions'] = native_transitions
end_start = len(text());chord('ctrl', 'end')
original_lines = csharp_original.split('\n')
wait_csharp_input(end_start,csharp_original,len(original_lines),len(original_lines[-1])+1,'Ctrl+End reaches actual model end')
enter_start = len(text());tap('ret')
wait_csharp_input(enter_start,csharp_original+'\n',len(original_lines)+1,1,'Enter creates actual final model line')
csharp_marker = '// xfenativecsharp'
for index, character in enumerate(csharp_marker):
character_start = len(text());type_text(character)
wait_csharp_input(character_start,csharp_original+'\n'+csharp_marker[:index+1],len(original_lines)+1,index+2,
'Physical C# character '+str(index+1)+' '+repr(character))
wait_body('Monaco - edited', csharp_edit_start, 30)
edited_actual, edited_verified = wait_csharp(csharp_edit_start, csharp_marker)
assert edited_actual['ModelValue'] == csharp_original + '\n' + csharp_marker, ('C# native model input was lost, duplicated or inserted at an unexpected position', edited_actual['ModelValue'])
csharp['EditedModelValue'] = edited_actual['ModelValue']
csharp['EditedDomReadback'] = edited_actual
csharp['EditedSpanColorParity'] = edited_verified
move(*pointer_away)
paint_deadline = time.monotonic() + 60
attempt = 0
while True:
attempt += 1
edited_csharp_frame = capture('Browser-OfficialMonaco-CSharp-Edited-' + str(attempt))
edited_csharp_paint = csharp_frame_stats(edited_csharp_frame, viewport, scale, edited_actual['ModelValue'], require_comment=True)
csharp['EditedFramebuffer'] = {'Attempts': attempt, **edited_csharp_paint}
if edited_csharp_paint['Passed'] or time.monotonic() >= paint_deadline:
break
assert all(item not in text() for item in ('CPU EXCEPTION:', '[FAILFAST]', '*** UNHANDLED EXCEPTION')), text()[-4000:]
time.sleep(.25)
assert edited_csharp_paint['Passed'], ('Edited C# actual model/newline/comment did not paint with the website comment color', edited_csharp_paint)
capture('Browser-OfficialMonaco-CSharp-Edited')
csharp['Passed'] = True
checks.append('physical native C# typing appends a real new model line and repaints every span with website colors including the new comment')
requested = [urlsplit(item['Path']).path for item in fixture.requests]
for expected in ('/Index', '/External.css', '/Classic.js', '/Defer.js', '/Dynamic.js'):
assert expected in requested, ('missing native peer request', expected, requested)
evidence['FixtureNonce'] = nonce; evidence['FixtureAddress'] = fixture.address
evidence['FixtureRequests'] = fixture.requests.copy()
evidence['FixtureResourcesSha256'] = {path: hashlib.sha256(source.encode('utf-8')).hexdigest() for path, (_, source) in fixture.resources.items()}
evidence['Passed'] = True
return evidence
except Exception as error:
evidence['Failure'] = str(error)
raise
finally:
fixture.close()
if output is not None:
(output / 'BrowserPipelinePeer.json').write_text(json.dumps({'Nonce': nonce, 'Address': fixture.address, 'Requests': fixture.requests}, ensure_ascii=False, indent=2), encoding='utf-8')
evidence['FixtureNonce'] = nonce; evidence['FixtureAddress'] = fixture.address; evidence['FixtureRequests'] = fixture.requests.copy()
evidence['FixtureResourcesSha256'] = {path: hashlib.sha256(source.encode('utf-8')).hexdigest() for path, (_, source) in fixture.resources.items()}
# The on-disk receipt also survives an assertion failure, including
# all original screenshot hashes and the final native paint measurements.
receipt_path = output / 'BrowserPipelineEvidence.json'
receipt_path.write_text(json.dumps(evidence, ensure_ascii=False, indent=2), encoding='utf-8')
evidence['EvidencePath'] = str(receipt_path)
evidence['EvidenceSha256'] = hashlib.sha256(receipt_path.read_bytes()).hexdigest()