P23-03: 生活の観察

This commit is contained in:
Agent Control Runner
2026-10-15 10:32:29 +09:00
parent 0b7727a66c
commit 21b5d3a31a
36 changed files with 4133 additions and 66 deletions
+210 -21
View File
@@ -288,27 +288,6 @@ class InfrastructureTests(unittest.TestCase):
if change == 'id': q[0]['ack']['sequence'] = 2
with self.assertRaises(ValueError): check.inspect_resume(writer, r, saved, q, members)
def test_rectangle_pixel_and_transform_negatives(self):
source = 'scripts/ui/pixel_people.gd'
colors = list(dict.fromkeys(check.re.findall(r'Color\("([0-9a-fA-F]{6})"', (check.ROOT/source).read_text())))
report = dict(rooms={}, landing_badges=[], cabins=[], resting_staff={}, badges=[],
actor_drawings=[dict(key='staff/s', staff=True, at=[1, 1], scale=1)])
row = dict(category='staff', id='staff/s', rect=[1, 1, 16, 18], viewport_rect=[1, 1, 16, 18],
screen_rect=[1, 1, 16, 18], style_source=source, style_colors=colors)
audit = dict(rows=[row])
matrix = [1, 0, 0, 1, 0, 0]
image = (24, 24, [[(113, 157, 148)]*24 for _ in range(24)])
self.assertEqual(check.compare_rectangles(report, audit, matrix, matrix, matrix, image), ['staff/staff/s'])
for change in ('rectangle', 'pixels', 'transform', 'coverage', 'palette'):
with self.subTest(change=change):
a, m, img = copy.deepcopy(audit), matrix[:], image
if change == 'rectangle': a['rows'][0]['rect'][0] += 1
if change == 'pixels': img = (24, 24, [[(0, 0, 0)]*24 for _ in range(24)])
if change == 'transform': m[4] = 10
if change == 'coverage': a['rows'].clear()
if change == 'palette': a['rows'][0]['style_colors'] = ['000000']
with self.assertRaises(ValueError): check.compare_rectangles(report, a, matrix, m, matrix, img)
def test_interpolation_history_tampering(self):
state = dict(systems=dict(runtime=dict(guests=dict(guests=[]), staff=dict(staff=[]),
elevators=dict(shafts=[], trips=[], current_minute=0))))
@@ -568,5 +547,215 @@ class ComparisonTests(unittest.TestCase):
check.compare_layouts(a, b)
class OfflineGeometryTests(unittest.TestCase):
"""Synthetic calibration examples; no OS or acceptance credit."""
def setUp(self):
self.calibration = dict(window_size=[100, 80], window_position=[240, 150],
screenshot_pixels=[200, 190], backing_scale=2,
canvas_stretch=1, titlebar_pixels=30)
self.request = dict(window_size=[100, 80], window_position=[240, 150],
screen_scale=2, content_scale_factor=1, target_pid=123)
self.clicks = [dict(target_pid=123, events=[dict(action='click',
coordinates=[20, 70], calibration=copy.deepcopy(self.calibration),
point=dict(screen=[10, 20], viewport=[10, 20],
viewport_to_screen=[1, 0, 0, 1, 0, 0]))])]
def transform(self):
return check.screenshot_transform(self.calibration, self.request, [200, 190], self.clicks)
def test_uses_measured_scale_origin_not_desktop_position(self):
self.assertEqual(check.affine_rect(self.transform(), [10, 20, 5, 7]), [20, 70, 10, 14])
def test_shifted_titlebar_fails_independent_click(self):
self.calibration['titlebar_pixels'] += 1
self.calibration['screenshot_pixels'][1] += 1
self.clicks[0]['events'][0]['calibration'] = copy.deepcopy(self.calibration)
with self.assertRaises(ValueError):
check.screenshot_transform(self.calibration, self.request, [200, 191], self.clicks)
def test_wrong_click_offset_fails(self):
self.clicks[0]['events'][0]['coordinates'][1] -= 30
with self.assertRaisesRegex(ValueError, 'click screenshot offset'):
self.transform()
def test_wrong_pid_cannot_calibrate(self):
self.clicks[0]['target_pid'] += 1
with self.assertRaisesRegex(ValueError, 'missing independent click'):
self.transform()
def test_nonfinite_and_false_scale_rejected(self):
for scale in (False, float('nan'), 0, -1):
self.calibration['backing_scale'] = scale
with self.assertRaisesRegex(ValueError, 'invalid screenshot calibration'):
self.transform()
def test_all_visibility_cases_are_accounted_for(self):
self.assertEqual(check.rectangle_eligibility([2, 3, 4, 5], [10, 10]),
('visible', [2, 3, 4, 5]))
self.assertEqual(check.rectangle_eligibility([-2, 3, 4, 5], [10, 10]),
('clipped', [0, 3, 2, 5]))
self.assertEqual(check.rectangle_eligibility([10, 3, 4, 5], [10, 10])[0], 'outside')
self.assertEqual(check.rectangle_eligibility([2, 3, 0, 5], [10, 10])[0], 'outside')
def test_invalid_rectangles_rejected(self):
for rect in ([0, 0, -1, 4], [float('nan'), 0, 1, 4]):
with self.assertRaisesRegex(ValueError, 'invalid clipping rectangle'):
check.rectangle_eligibility(rect, [10, 10])
def test_noise_is_measured_and_does_not_assert_class(self):
before = (2, 2, [[(10, 20, 30)]*2 for _ in range(2)])
after = copy.deepcopy(before)
after[2][1][1] = (10, 27, 30)
noise = check.paired_crop_noise(before, after, [0, 0, 2, 2])
self.assertEqual(noise, dict(samples=4, max_channel_delta=7,
mean_channel_delta=1.75, unchanged=3))
self.assertNotIn('pass', noise)
self.assertNotIn('state', noise)
def test_wrong_dimensions_and_empty_crop_rejected(self):
image = (1, 1, [[(0, 0, 0)]])
with self.assertRaisesRegex(ValueError, 'paired image dimensions'):
check.paired_crop_noise(image, (2, 1, []), [0, 0, 1, 1])
with self.assertRaisesRegex(ValueError, 'empty noise crop'):
check.paired_crop_noise(image, image, [1, 0, 1, 1])
def test_report_positions_and_source_provenance_are_recomputed(self):
source = 'scripts/ui/pixel_people.gd'
report = dict(rooms={}, landing_badges=[], cabins=[], resting_staff={}, badges=[],
actor_drawings=[dict(key='staff/s', staff=True, at=[1, 1], scale=1)])
colors = list(dict.fromkeys(check.re.findall(r'Color\("([0-9a-fA-F]{6})"',
(check.ROOT/source).read_text())))
audit = dict(rows=[dict(category='staff', id='staff/s', rect=[1, 1, 16, 18],
style_source=source, style_colors=colors)])
check.validate_drawing_rows(report, audit)
for change in ('shift', 'identity', 'missing', 'palette'):
tampered = copy.deepcopy(audit)
if change == 'shift': tampered['rows'][0]['rect'][0] += 1
if change == 'identity': tampered['rows'][0]['category'] = 'guest'
if change == 'missing': tampered['rows'] = []
if change == 'palette': tampered['rows'][0]['style_colors'] = ['000000']
with self.subTest(change=change), self.assertRaises(ValueError):
check.validate_drawing_rows(report, tampered)
class FrameReviewTests(unittest.TestCase):
def setUp(self):
OfflineGeometryTests.setUp(self)
self.request.update(local_to_viewport=[1, 0, 0, 1, 0, 0],
viewport_to_screen=[1, 0, 0, 1, 0, 0],
local_to_screen=[1, 0, 0, 1, 0, 0])
self.report = dict(layer=0, viewport=[100, 80], rooms={}, cabins=[],
landing_badges=[], badges=[], resting_staff={}, traffic=[],
actor_drawings=[dict(key='staff/s', staff=True, at=[1, 1], scale=1, state=0)])
source = 'scripts/ui/pixel_people.gd'
colors = list(dict.fromkeys(check.re.findall(r'Color\("([0-9a-fA-F]{6})"',
(check.ROOT/source).read_text())))
self.audit = dict(rows=[dict(category='staff', id='staff/s', rect=[1, 1, 16, 18],
viewport_rect=[1, 1, 16, 18], screen_rect=[1, 1, 16, 18],
style_source=source, style_colors=colors)])
self.image = (200, 190, [[(x % 256, y % 256, 0) for x in range(200)] for y in range(190)])
def frame(self):
return check.frame_rows(self.report, self.audit, self.request,
dict(calibration=self.calibration), [self.image], self.clicks)
def test_blank_crop_fails_without_threshold(self):
self.image = (200, 190, [[(0, 0, 0)] * 200 for _ in range(190)])
result = self.frame()
self.assertFalse(result['mechanical_pass'])
self.assertIn('blank crop', result['rows'][0]['failures'])
def test_missing_extra_and_unaudited_traffic_fail(self):
for change in ('missing', 'extra', 'traffic'):
with self.subTest(change=change):
original = copy.deepcopy(self.audit)
if change == 'missing': self.audit['rows'].clear()
if change == 'extra': self.audit['rows'] *= 2
if change == 'traffic':
self.report['traffic'] = [dict(cell=[-6, 2, 0], rect=[1, 1, 5, 5],
traffic=dict(current_density=1, temporary_block=False))]
result = self.frame()
self.assertFalse(result['mechanical_pass'])
self.assertEqual(len(result['rows']), len(self.audit['rows']))
self.assertIn('offline rectangle coverage', result['errors'])
self.audit = original
def test_dense_or_blocked_traffic_row_closes_audit_gap(self):
source = 'scenes/main/world_preview.gd'
colors = list(dict.fromkeys(check.re.findall(r'Color\("([0-9a-fA-F]{6})"',
(check.ROOT/source).read_text())))
for density, blocked in ((1, False), (0, True), (0, False)):
with self.subTest(density=density, blocked=blocked):
self.report['traffic'] = [dict(cell=[-6, 2, 0], rect=[1, 1, 5, 5],
traffic=dict(current_density=density, temporary_block=blocked))]
active = density > 0 or blocked
missing = self.frame()
self.assertEqual(missing['mechanical_pass'], not active)
if active:
self.assertIn('offline rectangle coverage', missing['errors'])
self.audit['rows'].append(dict(category='traffic', id='-6,2,0',
rect=[1, 1, 5, 5], viewport_rect=[1, 1, 5, 5],
screen_rect=[1, 1, 5, 5], style_source=source, style_colors=colors))
complete = self.frame()
self.assertTrue(complete['mechanical_pass'], complete['errors'])
self.audit['rows'].pop()
def test_wrong_state_enum_and_name_fail(self):
source = 'scripts/ui/pixel_tower_art.gd'
self.report['actor_drawings'] = []
room = dict(rect=[1, 1, 16, 18], state=3, state_name='NO_STAFF', operation=0)
self.report['rooms'] = {'r': room}
self.audit['rows'][0].update(category='room', id='r', style_source=source,
style_colors=list(dict.fromkeys(check.re.findall(r'Color\("([0-9a-fA-F]{6})"',
(check.ROOT/source).read_text()))))
self.assertEqual(self.frame()['rows'][0]['operation'], 'INACTIVE')
for state, name in ((99, 'NO_STAFF'), (3, 'OPEN'), (True, 'NO_ACCESS')):
room.update(state=state, state_name=name)
with self.assertRaises(ValueError): self.frame()
def test_frame_rejects_affine_and_calibration_shift(self):
self.request['local_to_screen'][4] += 1
with self.assertRaisesRegex(ValueError, 'affine composition'): self.frame()
self.request['local_to_screen'][4] -= 1
self.clicks[0]['events'][0]['coordinates'][1] += 1
with self.assertRaisesRegex(ValueError, 'click screenshot offset'): self.frame()
def test_eligible_crop_fully_outside_image_fails(self):
for key in ('viewport_to_screen', 'local_to_screen'):
self.request[key][4] = 300
self.audit['rows'][0]['screen_rect'][0] += 300
result = self.frame()
self.assertFalse(result['mechanical_pass'])
self.assertIn('eligible crop outside image', result['rows'][0]['failures'])
def test_manifest_crop_and_independent_review_binding(self):
with tempfile.TemporaryDirectory() as temporary:
directory = Path(temporary)
manifest, digest = check.write_frame_review(directory, self.frame(),
[dict(whole_image_sha256='a'*64, raw_sha256='b'*64, conversion_sha256='c'*64)])
self.assertEqual(check.sha(directory/'manifest.json'), digest)
crop = manifest['rows'][0]['crops'][0]
self.assertEqual(check.sha(directory/crop['path']), crop['sha256'])
self.assertEqual(check.png_pixels((directory/crop['path']).read_bytes())[:2], (32, 36))
verdict_path = directory/'independent-verdict.json'
self.assertEqual(check.reviewed_pixel_categories(manifest, digest, verdict_path), set())
verdict = dict(manifest_sha256=digest, reviewer='independent-opus-direct-image',
rows=[dict(row_index=0, category=True, state=True, position=True)])
for change in ('wrong_sha', 'missing_row', 'extra_row', 'rejected_state'):
bad = copy.deepcopy(verdict)
if change == 'wrong_sha': bad['manifest_sha256'] = '0'*64
if change == 'missing_row': bad['rows'] = []
if change == 'extra_row': bad['rows'] *= 2
if change == 'rejected_state': bad['rows'][0]['state'] = False
verdict_path.write_text(json.dumps(bad))
with self.subTest(change=change), self.assertRaises(ValueError):
check.reviewed_pixel_categories(manifest, digest, verdict_path)
verdict_path.write_text(json.dumps(verdict))
self.assertEqual(check.reviewed_pixel_categories(manifest, digest, verdict_path), {'staff'})
manifest['mechanical_pass'] = False
self.assertEqual(check.reviewed_pixel_categories(manifest, digest, verdict_path), set())
if __name__ == '__main__':
unittest.main()