Assistant: codex Assistant-Model: gpt-6-astra Assistant-Session: 01a10780-6d41-7952-9718-dfbc1f41236f
74 lines
4.2 KiB
Python
74 lines
4.2 KiB
Python
import json
|
|
from urllib.parse import urlencode
|
|
import uuid
|
|
|
|
from informed_decision.audit import OutboxWorker
|
|
from informed_decision.lifecycle_http import LifecycleAPI
|
|
from informed_decision.lifecycle_service import Caller
|
|
from informed_decision.runtime import Runtime
|
|
from informed_decision.web import App, SESSION_COOKIE
|
|
from informed_decision.oidc import ORIGIN
|
|
from informed_decision.policy import PolicyClient
|
|
from informed_decision.records import dumps
|
|
from test_browser_auth import login, signing_key, finish, call
|
|
from test_deployment_candidate import inputs, module
|
|
from test_durable_component import receiver
|
|
from test_lifecycle_http import call as api_call
|
|
from test_policy_client import PolicyTransport
|
|
from test_review_runtime import config
|
|
from test_skeleton import make_memo
|
|
|
|
|
|
def test_agent_to_human_collaboration_and_audit_without_configuration_changes(tmp_path, login, receiver):
|
|
path, configuration = config(tmp_path)
|
|
configuration['lifecycle_policy'] = {**configuration['policy'], 'package': 'informed-decision.lifecycle'}
|
|
configuration['lifecycle_delivery'] = True
|
|
path.write_text(json.dumps(configuration))
|
|
original_configuration = path.read_bytes()
|
|
runtime = Runtime.from_file(path)
|
|
transport = PolicyTransport()
|
|
transport.change = lambda data: data['provenance'].update(policy_package='informed-decision.lifecycle')
|
|
lifecycle = runtime.lifecycle
|
|
lifecycle.policy = PolicyClient('https://policy.test', lambda: 'synthetic-caller',
|
|
package='informed-decision.lifecycle', version='v1', package_digest=configuration['policy']['package_digest'],
|
|
transport=transport)
|
|
# Match the immutable configured digest in the simulated PDP return.
|
|
transport.change = lambda data: data['provenance'].update(
|
|
policy_package='informed-decision.lifecycle', policy_package_digest=configuration['policy']['package_digest'])
|
|
sid = finish(login)
|
|
session = login[0].session(sid)
|
|
from informed_decision.lifecycle import Attribution
|
|
from informed_decision.disposition import Actor, ActorKind
|
|
agent = Caller(Attribution(session.tenant.value, Actor('synthetic-agent', ActorKind.AGENT)),
|
|
session.expires_at, '{"principal_type_source":"authentication-derived"}')
|
|
def authenticate(token):
|
|
if token != 'fixture':
|
|
raise ValueError()
|
|
return agent
|
|
api = LifecycleAPI(lifecycle, authenticate)
|
|
app = App(login[0], runtime.controller, readiness=runtime.pump.ready, lifecycle=lifecycle)
|
|
cookie = f'{SESSION_COOKIE}={sid}'
|
|
memo = make_memo(id='agent-posed', approval_id=None, packet=(), highlights=())
|
|
status, receipt, _ = api_call(api, '/v1/decisions', method='POST', body={'memo': json.loads(dumps(memo))})
|
|
assert status == 200 and receipt['workspace_url'] == ORIGIN + '/decisions/agent-posed?version=1'
|
|
assert call(app, '/decisions/agent-posed', cookie=cookie)['status'] == 200
|
|
def post(action, **values):
|
|
values.update(csrf=session.csrf, key=str(uuid.uuid4()))
|
|
return call(app, '/decisions/agent-posed/' + action, 'POST', cookie=cookie, origin=ORIGIN,
|
|
body=urlencode(values).encode())
|
|
assert post('publish', version='1', subjects=session.subject, groups='')['status'] == 303
|
|
assert post('comment', version='1', text='Please add the alternative.')['status'] == 303
|
|
assert post('revise', version='1', question=memo.question, brief='Alternative added.', summary='Responded to feedback')['status'] == 303
|
|
assert api_call(api, '/v1/decisions/agent-posed')[1]['version'] == 2
|
|
from dataclasses import replace
|
|
second = replace(memo, id='second-agent-decision')
|
|
assert api_call(api, '/v1/decisions', method='POST', body={'memo': json.loads(dumps(second))},
|
|
HTTP_IDEMPOTENCY_KEY='second')[0] == 200
|
|
assert not runtime.pump.ready()
|
|
runtime.pump.worker = OutboxWorker(runtime.controller.store, receiver[0])
|
|
runtime.pump.tick()
|
|
assert runtime.pump.ready()
|
|
assert runtime.controller.store.lifecycle_counts() == {'records': 2, 'events': 5, 'pending': 0}
|
|
assert path.read_bytes() == original_configuration
|
|
assert runtime.controller.store.memos_for(memo.binding.principal.id) == []
|
|
assert api_call(api, '/v1/decisions/agent-posed/accept', method='POST', body={})[0] == 404
|