PASS CAS missing expected_revision -> 400 | got 400
PASS CAS correct revision -> 200 | got 200
PASS CAS stale revision -> 409 | got 409
PASS bad role_id -> 400 clean | 400 {'code': 'VALIDATION', 'message': '请求参数无效', 'request_id': 'req_8659e6703fbdfa63', 'error': '指定的角色不存在或已停用'}
PASS create user ok | 200 {'id': 36, 'username': 'beta6_user_1789891255', 'name': 'beta6验号', 'status': 'active', 'must_change_password': True, 'role_id': 'role-he', 'position': '验证员', 'created_at': '2026-09-20 08:00:55', 'updated_at': '2026-09-20 08:00:55'}
PASS change-password http | 200
PASS must_change_password cleared | top=False nested=False
PASS no project chat -> 403 ERR_NO_PROJECT | 403 {'error_code': 'ERR_NO_PROJECT', 'message': '请先创建或加入项目后再开始对话'}
PASS create project | 201
PASS duplicate name -> 409 | 409 {'error_code': 'ERR_DUPLICATE_PROJECT_NAME', 'message': '您已创建同名项目，请更换名称后重试'}
PASS client_key idempotent | 201 id=7 expected=7
PASS plain member add without perm -> 403 | 403 {'code': 'AUTHZ', 'message': '无权访问', 'request_id': 'req_ca5511b0c1e3039a', 'error': '{"error":"ERR_FORBIDDEN","message":"无权管理项目成员"}'}
PASS project member GET task-run -> 200 | 200
PASS non-member GET task-run -> 403 | 403 {'error_code': 'ERR_FORBIDDEN', 'message': '无权访问该任务'}
PASS CSP frame-src self blob | default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; font-src 'self'; img-src 'self' data: blob:; connect-src 'self'; frame-src 'self' blob:; frame-ancestors 'none'; base-uri 'self'; form-action 'self'; object-src 'none'
INFO role grant PATCH http=200
PASS after grant manage_members -> 200/201 | got add=True
PASS added member in list | mids=[4, 39, 36] target=36
PASS added member sees project in GET /projects | ids=[7]
