Integrate verified State Hub dispatcher into lifecycle release

Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a10780-6d41-7952-9718-dfbc1f41236f
This commit is contained in:
tegwick 2026-10-04 22:44:01 +02:00
parent 4898c9b764
commit c084600082
10 changed files with 361 additions and 16 deletions

View file

@ -164,13 +164,26 @@ from test_approval_component import component, signing_key
from test_durable_component import receiver
def test_actual_engine_human_entry_and_independent_audit_link_to_source_revision(handoff, component, receiver):
@pytest.mark.parametrize("via_dispatch", [False, True])
def test_actual_engine_human_entry_and_independent_audit_link_to_source_revision(handoff, component, receiver, tmp_path, via_dispatch):
import jwt
from informed_decision.intake_approval import IntakeApprovalClient
from informed_decision.approval_http import ApprovalHTTPClient
from informed_decision.review import ReviewController
from informed_decision.runtime import AuditPump
app, actor, memo, options, intake, calls = handoff
if via_dispatch:
import os, sys
source = os.environ.get('INFD_STATE_HUB_SOURCE')
if not source:
pytest.skip('State Hub source required for private dispatcher integration')
sys.path.insert(0, source)
from api.services.memo_dispatch import Dispatcher
options = {**options, 'memo_class': 'decision-record'}
grants = json.loads(intake.submitters_path.read_text())
for row in grants.values():
row['memo_classes'] = ['decision-record']
intake.submitters_path.write_text(json.dumps(grants))
client, engine, transport, human, signing = component
groups = json.loads(intake.groups_path.read_text())
groups[options['review_group']]['subject'] = human.subject
@ -183,8 +196,31 @@ def test_actual_engine_human_entry_and_independent_audit_link_to_source_revision
summary='Responded to research', key='revise')
app.publish(actor, memo.id, 2, audience={'subjects': [human.subject], 'groups': []}, key='publish-second')
receipt = app.request_review(actor, memo.id, 2, options=options, key='review-second')
status, loaded = request(intake, receipt['envelope'])
assert status == 201, loaded
if via_dispatch:
attempts = []
now = [time.time()]
def send(method, url, body, headers):
assert headers['Authorization'] == 'Bearer projected-token'
result = request(intake, body)
attempts.append(result[0])
if len(attempts) == 1:
raise OSError('lost reply after native creation')
return result
worker = Dispatcher(tmp_path / 'private-dispatch', send=send,
read_token=lambda: 'projected-token', clock=lambda: now[0])
assert worker.enqueue(receipt['envelope']).status == 'pending'
assert not attempts
assert worker.once().status == 'pending'
now[0] += 10
worker = Dispatcher(tmp_path / 'private-dispatch', send=send,
read_token=lambda: 'projected-token', clock=lambda: now[0])
forwarded = worker.once()
assert forwarded.status == 'delivered' and attempts == [201, 200]
loaded = forwarded.receipt
assert worker.once() is None
else:
status, loaded = request(intake, receipt['envelope'])
assert status == 201, loaded
controller = ReviewController(app.repository.store, policy(),
lambda session: ApprovalHTTPClient('https://approval.test', session, transport=transport), intake_attributes=True)
page = controller.open(human, receipt['review_memo_id'])