P23-03: 生活の観察

This commit is contained in:
Agent Control Runner
2026-10-15 18:30:42 +09:00
parent 19fc3f50c7
commit 9a26f9ab8c
4 changed files with 2172 additions and 4 deletions
+35 -3
View File
@@ -812,10 +812,10 @@ def compare_traffic(snapshot, report):
rows.append(dict(cell=cell, traffic={k: v for k, v in saved.items() if k != 'cell'},
rect=rect, band_rect=band))
close(report['traffic'], rows, 'traffic and cell rect')
validate_life_overlay(report)
validate_life_overlay(report, snapshot=snapshot)
def validate_life_overlay(report, root=ROOT):
def validate_life_overlay(report, root=ROOT, snapshot=None):
"""Check consumed frame and source wiring, not merely reported order flags."""
serial = report.get('observation_serial')
require(type(serial) is int and serial > 0
@@ -842,6 +842,25 @@ def validate_life_overlay(report, root=ROOT):
< overlay.find('_draw_observed_actor(actor, _life_overlay)')
< overlay.find('_draw_actors(_life_overlay)'), 'LifeOverlay source pass order')
actors = list(report['actor_drawings']) + [a for c in report['cabins'] for a in c['passengers']]
# Projection authority comes from raw state, never riding/region flags.
cabin_actors, carried_keys = set(), set()
if snapshot is not None:
if report['cabins']:
compare_cabin_geometry(snapshot, report)
shafts = {s['shaft_id']: s for s in elevator_report(snapshot)['shafts']}
for cabin in report['cabins']:
members = {key.replace('staff:', 'staff/', 1).replace('guest:', 'guest/', 1)
for key in shafts[cabin['shaft_id']]['boarded']}
cabin_actors.update(id(a) for a in cabin['passengers'] if a['key'] in members)
tasks = snapshot['systems']['runtime']['staff']['tasks']
carried_keys = {'staff/' + t['target_entity_id'] for t in tasks
if t['task_type'] == 'rescue_transport'
and t['state'] not in ('WORKING', 'COMPLETED', 'CANCELLED', 'FAILED')
and t['assigned_staff_id']}
carried_keys.difference_update(report.get('boarded', {}), report.get('queue_positions', {}))
if carried_keys:
# Reuse the original raw binding, track and raised-region fit checks.
compare_actor_geometry(snapshot, report)
for row in report.get('traffic', []):
x, y, w, h = row['rect']
thickness = max(2, min(5, h * .16))
@@ -850,11 +869,24 @@ def validate_life_overlay(report, root=ROOT):
close(row['band_rect'], expected, 'traffic band rectangle')
if row['traffic']['current_density'] <= 0 and not row['traffic']['temporary_block']:
continue
intervals = []
for actor in actors:
core = actor_identity_core(actor)
intersects = (core[0] < expected[0] + expected[2] and expected[0] < core[0] + core[2]
and core[1] < expected[1] + expected[3] and expected[1] < core[1] + core[3])
require(not intersects, 'traffic band covers actor core: ' + actor['key'])
require(not intersects or id(actor) in cabin_actors
or (actor in report['actor_drawings'] and actor['key'] in carried_keys),
'floor actor core over traffic band: ' + actor['key'])
if intersects:
intervals.append((max(core[0], expected[0]),
min(core[0] + core[2], expected[0] + expected[2])))
end = expected[0]
for left, right in sorted(intervals):
if left > end:
break
end = max(end, right)
require(end < expected[0] + expected[2],
'traffic band fully occluded: ' + str(row.get('cell')))
def compare_queues(snapshot, report):