P08-03: 配置の通常操作受入

This commit is contained in:
Agent Control Runner
2026-10-14 07:18:17 +09:00
parent 0c5e0022f2
commit 1f0a2bcd53
14 changed files with 6962 additions and 24 deletions
@@ -267,6 +267,31 @@ def coordinates(p):
expected = [matrix[0]*x+matrix[2]*y+matrix[4], matrix[1]*x+matrix[3]*y+matrix[5]]
require(len(p[target]) == 2 and all(abs(a-b) < 0.001 for a,b in zip(expected,p[target])), 'transformed '+target+' mismatch')
def dispatch_gate(p, events):
d = p['dispatch']
presses = [e for e in events if e.get('button') == 1 and e.get('pressed') is True]
require(len(presses) == 1 and presses[0].get('dispatch') == d
and presses[0]['position'] == d['viewport'], 'OS dispatch event mismatch')
for key in ('bounds', 'map_position', 'cell_dimensions', 'zoom', 'pan',
'viewport_transform', 'screen_transform'):
require(d[key] == p[key], 'OS dispatch transform drift')
x, y = d['local']
require(math.isfinite(x) and math.isfinite(y), 'OS nonfinite dispatch')
origin, size, bounds = d['map_position'], d['cell_dimensions'], d['bounds']
derived = [bounds['min_x'] + math.floor((x-origin[0])/size[0]),
bounds['max_y'] - math.floor((y-origin[1])/size[1]), p['world_cell'][2]]
require(d['world_cell'] == derived == p['world_cell'], 'OS actual input cell drift')
for target in ('viewport', 'screen'):
matrix = d[target+'_transform']
expected = [matrix[0]*x+matrix[2]*y+matrix[4], matrix[1]*x+matrix[3]*y+matrix[5]]
require(len(d[target]) == 2 and all(math.isfinite(v) for v in d[target])
and all(abs(a-b) < 0.001 for a,b in zip(expected,d[target])), 'OS dispatch coordinate drift')
selection = p['selection']
require(isinstance(selection['required'], bool), 'OS selection requirement')
if selection['required']:
require(selection['occupant_id'] and selection['entity_id'] == selection['occupant_id'],
'OS selected entity mismatch')
def preserve(a, b, results):
differences = typed_differences(a, b)
if not results:
@@ -644,6 +669,13 @@ def check(project_root, evidence_dir):
for key in ('screen_before', 'screen_after'):
png(artifact(ack[key]).read_bytes())
if request['action'] == 'cell' and 'position' in row:
dispatch_gate(row['position'], observed['events'])
if row['id'] == 'pan_zoom':
selection = row['position']['selection']
require(selection['required'], 'OS missing entity selection')
occupants = decode(document('os-pair/'+row['after']+'.json'))['systems']['runtime']['world']['occupancies']
matches = [o['entity_id'] for o in occupants if row['position']['world_cell'] in o['cells']]
require(matches == [selection['occupant_id']], 'OS selected occupancy mismatch')
require(request['world_cell'] == row['position']['world_cell']
and request['viewport'] == row['position']['viewport']
and request['screen'] == row['position']['screen'], 'OS transformed cell drift')
@@ -329,6 +329,41 @@ class EvidenceTests(unittest.TestCase):
self.edit('os-pair/unsupported-1/observed.json', lambda d: d.update(events=[]))
self.reject('missing OS events')
def test_os_dispatch_missing(self):
self.edit('os-pair/writer-actions.json', lambda d: d['actions'][0]['position'].pop('dispatch'))
self.reject('dispatch')
def test_os_wrong_actual_input_cell(self):
# Keep event and action mutually consistent; independent conversion must reject.
self.edit('os-pair/writer-actions.json', lambda d: d['actions'][0]['position']['dispatch']['world_cell'].__setitem__(0, 99))
self.edit('os-pair/unsupported-1/observed.json', lambda d: d['events'][0]['dispatch']['world_cell'].__setitem__(0, 99))
self.reject('OS actual input cell drift')
def test_os_event_position_disagrees(self):
self.edit('os-pair/unsupported-1/observed.json', lambda d: d['events'][0].update(position=[0,0]))
self.reject('OS dispatch event mismatch')
def test_os_wrong_selected_entity(self):
self.edit('os-pair/writer-actions.json', lambda d: d['actions'][-1]['position']['selection'].update(entity_id='wrong'))
self.reject('OS selected entity mismatch')
def test_os_wrong_selected_occupancy(self):
self.edit('os-pair/writer-actions.json', lambda d: d['actions'][-1]['position']['selection'].update(entity_id='wrong', occupant_id='wrong'))
self.reject('OS selected occupancy mismatch')
def test_os_selection_requirement_cannot_be_removed(self):
self.edit('os-pair/writer-actions.json', lambda d: d['actions'][-1]['position']['selection'].update(required=False))
self.reject('OS missing entity selection')
def test_os_dispatch_transform_drift(self):
self.edit('os-pair/writer-actions.json', lambda d: d['actions'][0]['position']['dispatch'].update(pan=[100,0]))
self.edit('os-pair/unsupported-1/observed.json', lambda d: d['events'][0]['dispatch'].update(pan=[100,0]))
self.reject('OS dispatch transform drift')
def test_os_later_getter_is_diagnostic(self):
self.edit('os-pair/writer-actions.json', lambda d: d['actions'][-1]['position']['diagnostics'].update(getter_cell=[999,999,0]))
self.assertEqual([], C.check(self.root, self.out))
def test_os_ack_for_another_request(self):
self.edit('os-pair/unsupported-1/ack.json', lambda d: d.update(request_sha256='0'*64))
self.reject('OS ack request mismatch')