Files
EvoScientist-Multi/tests/b03_pending_pure.py
T
m4 d4b53bfb08
Docker / build (push) Has been cancelled
Test / pytest (ubuntu-latest, 3.12) (push) Has been cancelled
Test / pytest (windows-latest, 3.11) (push) Has been cancelled
Test / pytest (windows-latest, 3.12) (push) Has been cancelled
Lint / ruff (push) Has been cancelled
Test / pytest (ubuntu-latest, 3.11) (push) Has been cancelled
Build / build (push) Has been cancelled
test: cover stop contract, execution adapters, checkpointer race and runtime identity
2026-09-13 15:12:17 +08:00

70 lines
3.8 KiB
Python

"""Budgeted stdlib-only public pending regression; no application imports."""
import ast
import hashlib
import json
import sys
from collections.abc import Mapping
from pathlib import Path
from types import SimpleNamespace
from typing import Any
ROOT = Path(__file__).resolve().parents[2]
sys.path.insert(0, str(ROOT / 'Ai4Sci-Web'))
LOG = ROOT / '.hermes/test-runtime/unified-execution/b03-host'
ledger = LOG / 'pending-pure-attempts.jsonl'
records = [json.loads(x) for x in ledger.read_text().splitlines()] if ledger.exists() else []
attempt = 1 + sum(x['phase'] == 'start' for x in records)
assert attempt <= 5
with ledger.open('a') as f:
f.write(json.dumps(dict(phase='start', node='test_pending_display_allowlist', attempt=attempt, limit=5)) + '\n')
ns: dict[str, Any] = dict(Any=Any, Mapping=Mapping, hashlib=hashlib, json=json,
ProjectionEvent=lambda **kw: SimpleNamespace(**kw),
ProjectionSource=lambda **kw: kw, ItemActor=lambda **kw: kw)
for filename, names in [
('pending_display.py', None),
('recoverable_runs.py', {'canonical_json', 'content_hash', '_value', '_mapping', '_safe_json', 'normalize_interrupt'}),
('projection_event_adapter.py', {'_safe', 'pending_input_projection_event'}),
]:
path = ROOT / 'Ai4Sci-Web/gateway/services' / filename
if not path.exists():
continue
tree = ast.parse(path.read_text())
body = [n for n in tree.body if isinstance(n, ast.FunctionDef) and (names is None or n.name in names)]
if names is None:
body = [n for n in tree.body if isinstance(n, (ast.FunctionDef, ast.Assign, ast.Import, ast.ImportFrom))]
exec(compile(ast.Module(body=body, type_ignores=[]), str(path), 'exec'), ns)
sentinel = 'b03-private-' + 'canary-7f9a'
raw = {'id': 'stable-id', 'value': {
'action_requests': [{'name': 'execute', 'args': {'command': 'printf ' + sentinel, 'checkpoint_details': {'x': sentinel}},
'description': 'Tool: execute Args: ' + sentinel, 'checkpoint_details': {'x': [sentinel]}}],
'review_configs': [{'action_name': 'execute', 'allowed_decisions': ['approve', 'reject'], 'checkpoint_details': {'x': sentinel}}],
'checkpoint_details': {'x': sentinel}}}
before = ns['content_hash'](raw)
expected_payload = ns['_safe_json'](raw['value'])
pending = ns['normalize_interrupt'](raw)
event = ns['pending_input_projection_event'](pending, message_id='m', run_id='r', source_sequence=1)
public = json.dumps([pending['safe_payload'], pending['event'], event.payload])
action = event.payload['display_payload']['action_requests'][0]
checks = {
'public_has_no_sentinel': sentinel not in public,
'no_unknown_nested_fields': 'checkpoint_details' not in public,
'description_regenerated': sentinel not in action['description'] and 'printf' in action['description'],
'command_visible': 'printf' in json.dumps(action['args']),
'internal_payload_unchanged': pending['payload'] == expected_payload,
'decision_hash_unchanged': pending['payload_hash'] == ns['content_hash'](expected_payload),
'raw_hash_unchanged': before == ns['content_hash'](raw),
'identity_compatible': pending['interrupt_id'] == raw['id'] and event.payload['payload_hash'] == pending['payload_hash'],
'review_reject_only': pending['safe_payload']['review_configs'][0]['allowed_decisions'] == ['reject'],
}
# Also test an older stored safe_payload passed directly to the projector.
legacy = dict(pending, safe_payload=raw['value'])
legacy_event = ns['pending_input_projection_event'](legacy, message_id='m', run_id='r', source_sequence=2)
checks['legacy_projection_safe'] = sentinel not in json.dumps(legacy_event.payload)
passed = all(checks.values())
result = json.dumps(checks)
(LOG / f'pending-pure-{attempt}.log').write_text(result + '\n')
with ledger.open('a') as f:
f.write(json.dumps(dict(phase='result', attempt=attempt, passed=passed)) + '\n')
print(result)
raise SystemExit(0 if passed else 1)