hawk 3.2.0__tar.gz → 3.3.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (987) hide show
  1. {hawk-3.2.0 → hawk-3.3.0}/.dockerignore +0 -16
  2. {hawk-3.2.0 → hawk-3.3.0}/CHANGELOG.md +18 -0
  3. {hawk-3.2.0 → hawk-3.3.0}/Dockerfile +23 -11
  4. {hawk-3.2.0 → hawk-3.3.0}/PKG-INFO +1 -1
  5. {hawk-3.2.0 → hawk-3.3.0}/hawk/api/EvalSetConfig.schema.json +50 -2
  6. {hawk-3.2.0 → hawk-3.3.0}/hawk/api/human_eval_server.py +12 -10
  7. {hawk-3.2.0 → hawk-3.3.0}/hawk/api/meta_server.py +27 -1
  8. hawk-3.3.0/hawk/core/db/alembic/versions/a726f26fdd42_scan_model_groups_inherit_eval_groups.py +174 -0
  9. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/db/functions.py +49 -20
  10. hawk-3.3.0/hawk/core/db/scan_writes.py +58 -0
  11. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/importer/eval/writer/postgres.py +17 -1
  12. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/scan_export.py +21 -8
  13. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/shell.py +11 -23
  14. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/types/__init__.py +2 -0
  15. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/types/evals.py +69 -16
  16. {hawk-3.2.0 → hawk-3.3.0}/hawk/runner/common.py +23 -13
  17. {hawk-3.2.0 → hawk-3.3.0}/hawk/runner/credential_helper.py +225 -27
  18. {hawk-3.2.0 → hawk-3.3.0}/hawk/runner/run_eval_set.py +66 -43
  19. {hawk-3.2.0 → hawk-3.3.0}/pyproject.toml +16 -8
  20. hawk-3.3.0/scripts/runner/dummy/Dockerfile +8 -0
  21. hawk-3.3.0/scripts/runner/dummy/entrypoint.sh +18 -0
  22. {hawk-3.2.0 → hawk-3.3.0}/services/modules/docker_lambda/Dockerfile +43 -22
  23. {hawk-3.2.0 → hawk-3.3.0}/services/modules/eval_log_importer/Dockerfile +14 -11
  24. {hawk-3.2.0 → hawk-3.3.0}/services/modules/eval_log_importer/uv.lock +2 -2
  25. {hawk-3.2.0 → hawk-3.3.0}/services/modules/eval_log_reader/uv.lock +2 -2
  26. {hawk-3.2.0 → hawk-3.3.0}/services/modules/job_status_updated/uv.lock +2 -2
  27. {hawk-3.2.0 → hawk-3.3.0}/services/modules/sample_editor/Dockerfile +14 -11
  28. {hawk-3.2.0 → hawk-3.3.0}/services/modules/sample_editor/uv.lock +2 -2
  29. {hawk-3.2.0 → hawk-3.3.0}/services/modules/scan_importer/uv.lock +2 -2
  30. {hawk-3.2.0 → hawk-3.3.0}/services/modules/token_broker/tests/test_handler.py +87 -1
  31. {hawk-3.2.0 → hawk-3.3.0}/services/modules/token_broker/token_broker/index.py +47 -1
  32. {hawk-3.2.0 → hawk-3.3.0}/services/modules/token_broker/token_broker/types.py +16 -1
  33. {hawk-3.2.0 → hawk-3.3.0}/services/modules/token_broker/uv.lock +2 -2
  34. hawk-3.3.0/services/modules/viewer/Dockerfile.dockerignore +22 -0
  35. {hawk-3.2.0 → hawk-3.3.0}/tests/api/test_human_eval_server.py +7 -2
  36. {hawk-3.2.0 → hawk-3.3.0}/tests/api/test_scan_export.py +100 -1
  37. {hawk-3.2.0 → hawk-3.3.0}/tests/core/db/test_alembic_migrations.py +147 -0
  38. {hawk-3.2.0 → hawk-3.3.0}/tests/core/db/test_rls.py +66 -3
  39. {hawk-3.2.0 → hawk-3.3.0}/tests/core/importer/eval/test_writer_postgres.py +115 -1
  40. {hawk-3.2.0 → hawk-3.3.0}/tests/core/test_scan_export.py +4 -17
  41. {hawk-3.2.0 → hawk-3.3.0}/tests/core/test_shell.py +3 -3
  42. {hawk-3.2.0 → hawk-3.3.0}/tests/core/types/test_evals.py +38 -2
  43. {hawk-3.2.0 → hawk-3.3.0}/tests/runner/conftest.py +36 -1
  44. {hawk-3.2.0 → hawk-3.3.0}/tests/runner/test_common.py +21 -0
  45. {hawk-3.2.0 → hawk-3.3.0}/tests/runner/test_credential_helper.py +479 -3
  46. {hawk-3.2.0 → hawk-3.3.0}/tests/runner/test_run_eval_set.py +104 -11
  47. hawk-3.3.0/tests/smoke/eval_sets/adaptive_connections.yaml +31 -0
  48. hawk-3.3.0/tests/smoke/scenarios/test_adaptive_connections.py +37 -0
  49. {hawk-3.2.0 → hawk-3.3.0}/uv.lock +3 -3
  50. hawk-3.2.0/scripts/runner/dummy/Dockerfile +0 -9
  51. hawk-3.2.0/scripts/runner/dummy/entrypoint.sh +0 -17
  52. {hawk-3.2.0 → hawk-3.3.0}/.cursor/rules/api-patterns.mdc +0 -0
  53. {hawk-3.2.0 → hawk-3.3.0}/.cursor/rules/architecture.mdc +0 -0
  54. {hawk-3.2.0 → hawk-3.3.0}/.cursor/rules/cli-structure.mdc +0 -0
  55. {hawk-3.2.0 → hawk-3.3.0}/.cursor/rules/dev-workflow.mdc +0 -0
  56. {hawk-3.2.0 → hawk-3.3.0}/.cursor/rules/kubernetes-helm.mdc +0 -0
  57. {hawk-3.2.0 → hawk-3.3.0}/.cursor/rules/python-standards.mdc +0 -0
  58. {hawk-3.2.0 → hawk-3.3.0}/.cursor/rules/testing-patterns.mdc +0 -0
  59. {hawk-3.2.0 → hawk-3.3.0}/.editorconfig +0 -0
  60. {hawk-3.2.0 → hawk-3.3.0}/.env.example +0 -0
  61. {hawk-3.2.0 → hawk-3.3.0}/.gitattributes +0 -0
  62. {hawk-3.2.0 → hawk-3.3.0}/.github/workflows/weekly-release.yaml +0 -0
  63. {hawk-3.2.0 → hawk-3.3.0}/.gitignore +0 -0
  64. {hawk-3.2.0 → hawk-3.3.0}/.mcp.json +0 -0
  65. {hawk-3.2.0 → hawk-3.3.0}/.mentat/precommit.sh +0 -0
  66. {hawk-3.2.0 → hawk-3.3.0}/.mentat/setup.sh +0 -0
  67. {hawk-3.2.0 → hawk-3.3.0}/.python-version +0 -0
  68. {hawk-3.2.0 → hawk-3.3.0}/AGENTS.md +0 -0
  69. {hawk-3.2.0 → hawk-3.3.0}/CLAUDE.md +0 -0
  70. {hawk-3.2.0 → hawk-3.3.0}/README.md +0 -0
  71. {hawk-3.2.0 → hawk-3.3.0}/demo/docker_in_sandbox_task/README.md +0 -0
  72. {hawk-3.2.0 → hawk-3.3.0}/demo/docker_in_sandbox_task/docker_in_sandbox_task/__init__.py +0 -0
  73. {hawk-3.2.0 → hawk-3.3.0}/demo/docker_in_sandbox_task/docker_in_sandbox_task/_registry.py +0 -0
  74. {hawk-3.2.0 → hawk-3.3.0}/demo/docker_in_sandbox_task/docker_in_sandbox_task/docker-enabled.sleep.values.yaml +0 -0
  75. {hawk-3.2.0 → hawk-3.3.0}/demo/docker_in_sandbox_task/docker_in_sandbox_task/docker-enabled.values.yaml +0 -0
  76. {hawk-3.2.0 → hawk-3.3.0}/demo/docker_in_sandbox_task/docker_in_sandbox_task/task.py +0 -0
  77. {hawk-3.2.0 → hawk-3.3.0}/demo/docker_in_sandbox_task/pyproject.toml +0 -0
  78. {hawk-3.2.0 → hawk-3.3.0}/docker/warehouse-init.sql +0 -0
  79. {hawk-3.2.0 → hawk-3.3.0}/docker-compose.debug.yaml +0 -0
  80. {hawk-3.2.0 → hawk-3.3.0}/docker-compose.yaml +0 -0
  81. {hawk-3.2.0 → hawk-3.3.0}/docs/Architecture.md +0 -0
  82. {hawk-3.2.0 → hawk-3.3.0}/docs/debugging-stuck-evals.md +0 -0
  83. {hawk-3.2.0 → hawk-3.3.0}/docs/solutions/smoke-test-failures/investigating-batch-import-failures.md +0 -0
  84. {hawk-3.2.0 → hawk-3.3.0}/docs/solutions/test-failures/mock-scoping.md +0 -0
  85. {hawk-3.2.0 → hawk-3.3.0}/docs/superpowers/plans/2026-05-04-adaptive-connections.md +0 -0
  86. {hawk-3.2.0 → hawk-3.3.0}/docs/superpowers/specs/2026-05-04-adaptive-connections-design.md +0 -0
  87. {hawk-3.2.0 → hawk-3.3.0}/examples/acp-approval.eval-set.yaml +0 -0
  88. {hawk-3.2.0 → hawk-3.3.0}/examples/acp_babysitter.py +0 -0
  89. {hawk-3.2.0 → hawk-3.3.0}/examples/checkpointing.eval-set.yaml +0 -0
  90. {hawk-3.2.0 → hawk-3.3.0}/examples/docker-in-sandbox.eval-set.yaml +0 -0
  91. {hawk-3.2.0 → hawk-3.3.0}/examples/human-baseline.eval-set.yaml +0 -0
  92. {hawk-3.2.0 → hawk-3.3.0}/examples/simple-with-aws-secret.eval-set.yaml +0 -0
  93. {hawk-3.2.0 → hawk-3.3.0}/examples/simple-with-secrets.eval-set.yaml +0 -0
  94. {hawk-3.2.0 → hawk-3.3.0}/examples/simple.eval-set.yaml +0 -0
  95. {hawk-3.2.0 → hawk-3.3.0}/examples/simple.scan.yaml +0 -0
  96. {hawk-3.2.0 → hawk-3.3.0}/hawk/__init__.py +0 -0
  97. {hawk-3.2.0 → hawk-3.3.0}/hawk/__main__.py +0 -0
  98. {hawk-3.2.0 → hawk-3.3.0}/hawk/api/ScanConfig.schema.json +0 -0
  99. {hawk-3.2.0 → hawk-3.3.0}/hawk/api/__init__.py +0 -0
  100. {hawk-3.2.0 → hawk-3.3.0}/hawk/api/auth/__init__.py +0 -0
  101. {hawk-3.2.0 → hawk-3.3.0}/hawk/api/auth/access_token.py +0 -0
  102. {hawk-3.2.0 → hawk-3.3.0}/hawk/api/auth/job_auth.py +0 -0
  103. {hawk-3.2.0 → hawk-3.3.0}/hawk/api/auth/middleman_client.py +0 -0
  104. {hawk-3.2.0 → hawk-3.3.0}/hawk/api/auth/permission_checker.py +0 -0
  105. {hawk-3.2.0 → hawk-3.3.0}/hawk/api/auth/read_only.py +0 -0
  106. {hawk-3.2.0 → hawk-3.3.0}/hawk/api/auth/s3_files.py +0 -0
  107. {hawk-3.2.0 → hawk-3.3.0}/hawk/api/auth_router.py +0 -0
  108. {hawk-3.2.0 → hawk-3.3.0}/hawk/api/cors_middleware.py +0 -0
  109. {hawk-3.2.0 → hawk-3.3.0}/hawk/api/cross_lab.py +0 -0
  110. {hawk-3.2.0 → hawk-3.3.0}/hawk/api/datadog.py +0 -0
  111. {hawk-3.2.0 → hawk-3.3.0}/hawk/api/datadog_monitors.py +0 -0
  112. {hawk-3.2.0 → hawk-3.3.0}/hawk/api/eval_log_server.py +0 -0
  113. {hawk-3.2.0 → hawk-3.3.0}/hawk/api/eval_set_server.py +0 -0
  114. {hawk-3.2.0 → hawk-3.3.0}/hawk/api/event_serialization.py +0 -0
  115. {hawk-3.2.0 → hawk-3.3.0}/hawk/api/health.py +0 -0
  116. {hawk-3.2.0 → hawk-3.3.0}/hawk/api/helm_chart/Chart.yaml +0 -0
  117. {hawk-3.2.0 → hawk-3.3.0}/hawk/api/helm_chart/templates/config_map.yaml +0 -0
  118. {hawk-3.2.0 → hawk-3.3.0}/hawk/api/helm_chart/templates/job.yaml +0 -0
  119. {hawk-3.2.0 → hawk-3.3.0}/hawk/api/helm_chart/templates/namespace.yaml +0 -0
  120. {hawk-3.2.0 → hawk-3.3.0}/hawk/api/helm_chart/templates/network_policy.yaml +0 -0
  121. {hawk-3.2.0 → hawk-3.3.0}/hawk/api/helm_chart/templates/secret.yaml +0 -0
  122. {hawk-3.2.0 → hawk-3.3.0}/hawk/api/helm_chart/templates/service_account.yaml +0 -0
  123. {hawk-3.2.0 → hawk-3.3.0}/hawk/api/human_server.py +0 -0
  124. {hawk-3.2.0 → hawk-3.3.0}/hawk/api/import_common.py +0 -0
  125. {hawk-3.2.0 → hawk-3.3.0}/hawk/api/import_server.py +0 -0
  126. {hawk-3.2.0 → hawk-3.3.0}/hawk/api/inspect_async_fs.py +0 -0
  127. {hawk-3.2.0 → hawk-3.3.0}/hawk/api/jumphost.py +0 -0
  128. {hawk-3.2.0 → hawk-3.3.0}/hawk/api/monitoring_server.py +0 -0
  129. {hawk-3.2.0 → hawk-3.3.0}/hawk/api/otel.py +0 -0
  130. {hawk-3.2.0 → hawk-3.3.0}/hawk/api/platform_metrics.py +0 -0
  131. {hawk-3.2.0 → hawk-3.3.0}/hawk/api/presigned_urls.py +0 -0
  132. {hawk-3.2.0 → hawk-3.3.0}/hawk/api/problem.py +0 -0
  133. {hawk-3.2.0 → hawk-3.3.0}/hawk/api/run.py +0 -0
  134. {hawk-3.2.0 → hawk-3.3.0}/hawk/api/sample_access.py +0 -0
  135. {hawk-3.2.0 → hawk-3.3.0}/hawk/api/sample_content_router.py +0 -0
  136. {hawk-3.2.0 → hawk-3.3.0}/hawk/api/sample_edit_router.py +0 -0
  137. {hawk-3.2.0 → hawk-3.3.0}/hawk/api/sample_events_router.py +0 -0
  138. {hawk-3.2.0 → hawk-3.3.0}/hawk/api/scan_import_server.py +0 -0
  139. {hawk-3.2.0 → hawk-3.3.0}/hawk/api/scan_server.py +0 -0
  140. {hawk-3.2.0 → hawk-3.3.0}/hawk/api/scan_view_server.py +0 -0
  141. {hawk-3.2.0 → hawk-3.3.0}/hawk/api/server.py +0 -0
  142. {hawk-3.2.0 → hawk-3.3.0}/hawk/api/server_policies.py +0 -0
  143. {hawk-3.2.0 → hawk-3.3.0}/hawk/api/settings.py +0 -0
  144. {hawk-3.2.0 → hawk-3.3.0}/hawk/api/state.py +0 -0
  145. {hawk-3.2.0 → hawk-3.3.0}/hawk/api/timeline.py +0 -0
  146. {hawk-3.2.0 → hawk-3.3.0}/hawk/api/transcript_search_cache.py +0 -0
  147. {hawk-3.2.0 → hawk-3.3.0}/hawk/api/transcript_search_router.py +0 -0
  148. {hawk-3.2.0 → hawk-3.3.0}/hawk/api/usage_server.py +0 -0
  149. {hawk-3.2.0 → hawk-3.3.0}/hawk/api/util/aiohttp_to_starlette.py +0 -0
  150. {hawk-3.2.0 → hawk-3.3.0}/hawk/api/util/namespace.py +0 -0
  151. {hawk-3.2.0 → hawk-3.3.0}/hawk/api/util/validation.py +0 -0
  152. {hawk-3.2.0 → hawk-3.3.0}/hawk/api/yaml_safety.py +0 -0
  153. {hawk-3.2.0 → hawk-3.3.0}/hawk/cli/__init__.py +0 -0
  154. {hawk-3.2.0 → hawk-3.3.0}/hawk/cli/acp.py +0 -0
  155. {hawk-3.2.0 → hawk-3.3.0}/hawk/cli/cli.py +0 -0
  156. {hawk-3.2.0 → hawk-3.3.0}/hawk/cli/config.py +0 -0
  157. {hawk-3.2.0 → hawk-3.3.0}/hawk/cli/delete.py +0 -0
  158. {hawk-3.2.0 → hawk-3.3.0}/hawk/cli/download.py +0 -0
  159. {hawk-3.2.0 → hawk-3.3.0}/hawk/cli/download_artifacts.py +0 -0
  160. {hawk-3.2.0 → hawk-3.3.0}/hawk/cli/edit_samples.py +0 -0
  161. {hawk-3.2.0 → hawk-3.3.0}/hawk/cli/eval_set.py +0 -0
  162. {hawk-3.2.0 → hawk-3.3.0}/hawk/cli/human.py +0 -0
  163. {hawk-3.2.0 → hawk-3.3.0}/hawk/cli/human_eval.py +0 -0
  164. {hawk-3.2.0 → hawk-3.3.0}/hawk/cli/import_cmd.py +0 -0
  165. {hawk-3.2.0 → hawk-3.3.0}/hawk/cli/list.py +0 -0
  166. {hawk-3.2.0 → hawk-3.3.0}/hawk/cli/local.py +0 -0
  167. {hawk-3.2.0 → hawk-3.3.0}/hawk/cli/login.py +0 -0
  168. {hawk-3.2.0 → hawk-3.3.0}/hawk/cli/middleman.py +0 -0
  169. {hawk-3.2.0 → hawk-3.3.0}/hawk/cli/models.py +0 -0
  170. {hawk-3.2.0 → hawk-3.3.0}/hawk/cli/monitoring.py +0 -0
  171. {hawk-3.2.0 → hawk-3.3.0}/hawk/cli/scan.py +0 -0
  172. {hawk-3.2.0 → hawk-3.3.0}/hawk/cli/scan_import.py +0 -0
  173. {hawk-3.2.0 → hawk-3.3.0}/hawk/cli/seed/__init__.py +0 -0
  174. {hawk-3.2.0 → hawk-3.3.0}/hawk/cli/seed/constants.py +0 -0
  175. {hawk-3.2.0 → hawk-3.3.0}/hawk/cli/seed/eval_log.py +0 -0
  176. {hawk-3.2.0 → hawk-3.3.0}/hawk/cli/seed/seeder.py +0 -0
  177. {hawk-3.2.0 → hawk-3.3.0}/hawk/cli/ssh_probe.py +0 -0
  178. {hawk-3.2.0 → hawk-3.3.0}/hawk/cli/stacktrace.py +0 -0
  179. {hawk-3.2.0 → hawk-3.3.0}/hawk/cli/stop.py +0 -0
  180. {hawk-3.2.0 → hawk-3.3.0}/hawk/cli/tokens.py +0 -0
  181. {hawk-3.2.0 → hawk-3.3.0}/hawk/cli/trace.py +0 -0
  182. {hawk-3.2.0 → hawk-3.3.0}/hawk/cli/transcript.py +0 -0
  183. {hawk-3.2.0 → hawk-3.3.0}/hawk/cli/usage.py +0 -0
  184. {hawk-3.2.0 → hawk-3.3.0}/hawk/cli/util/api.py +0 -0
  185. {hawk-3.2.0 → hawk-3.3.0}/hawk/cli/util/auth.py +0 -0
  186. {hawk-3.2.0 → hawk-3.3.0}/hawk/cli/util/import_upload.py +0 -0
  187. {hawk-3.2.0 → hawk-3.3.0}/hawk/cli/util/model.py +0 -0
  188. {hawk-3.2.0 → hawk-3.3.0}/hawk/cli/util/responses.py +0 -0
  189. {hawk-3.2.0 → hawk-3.3.0}/hawk/cli/util/secrets.py +0 -0
  190. {hawk-3.2.0 → hawk-3.3.0}/hawk/cli/util/table.py +0 -0
  191. {hawk-3.2.0 → hawk-3.3.0}/hawk/cli/util/trace.py +0 -0
  192. {hawk-3.2.0 → hawk-3.3.0}/hawk/cli/util/types.py +0 -0
  193. {hawk-3.2.0 → hawk-3.3.0}/hawk/cli/util/urls.py +0 -0
  194. {hawk-3.2.0 → hawk-3.3.0}/hawk/cli/util/version_check.py +0 -0
  195. {hawk-3.2.0 → hawk-3.3.0}/hawk/cli/watch.py +0 -0
  196. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/__init__.py +0 -0
  197. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/auth/__init__.py +0 -0
  198. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/auth/auth_context.py +0 -0
  199. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/auth/jwt_validator.py +0 -0
  200. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/auth/model_file.py +0 -0
  201. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/auth/permissions.py +0 -0
  202. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/aws_secret_arns.py +0 -0
  203. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/constants.py +0 -0
  204. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/db/__init__.py +0 -0
  205. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/db/alembic/env.py +0 -0
  206. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/db/alembic/script.py.mako +0 -0
  207. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/db/alembic/versions/0844cd8afa68_score_unique.py +0 -0
  208. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/db/alembic/versions/0a15eda2d9f5_token_counts_input.py +0 -0
  209. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/db/alembic/versions/0ac1d8003bb0_normalize_stringly_typed_middleman_.py +0 -0
  210. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/db/alembic/versions/1bec8cf5d1cf_add_cost_limit_tracking.py +0 -0
  211. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/db/alembic/versions/20260517_add_sample_attachment.py +0 -0
  212. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/db/alembic/versions/222b2ff7c35d_add_checkpoint_and_interrupt_event_columns.py +0 -0
  213. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/db/alembic/versions/28a263b7cf62_event_field_parity.py +0 -0
  214. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/db/alembic/versions/29d00d0f0dc2_add_label_to_scanner_result_unique_.py +0 -0
  215. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/db/alembic/versions/2b1533ceff67_add_code_access_control_schema.py +0 -0
  216. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/db/alembic/versions/320517503c48_index_score_events_on_event_search_tsv.py +0 -0
  217. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/db/alembic/versions/3af9c05e1d76_model_access_public_ordinary_group.py +0 -0
  218. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/db/alembic/versions/40285195f664_merge_heads.py +0 -0
  219. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/db/alembic/versions/4b7e1f9c2a3d_add_event_uuid_index.py +0 -0
  220. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/db/alembic/versions/4c2997c12c77_add_cancelled_and_sandbox_unavailable_.py +0 -0
  221. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/db/alembic/versions/51110e2216a6_add_history_to_score.py +0 -0
  222. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/db/alembic/versions/549e90e5525c_add_sample_event_table.py +0 -0
  223. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/db/alembic/versions/5d72524d723a_init.py +0 -0
  224. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/db/alembic/versions/5e3b8f2a91c4_backfill_are_details_secret.py +0 -0
  225. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/db/alembic/versions/65dbc6ab948e_merge_branch_anchor_events_with_human_.py +0 -0
  226. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/db/alembic/versions/6b2b4bf2feaa_key_model_role_uniqueness_by_model_as_.py +0 -0
  227. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/db/alembic/versions/6c0a6ce96105_add_sample_started_completed_timestamps.py +0 -0
  228. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/db/alembic/versions/70562d043fe1_add_job_table.py +0 -0
  229. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/db/alembic/versions/7161087c5d94_cascade_deletes_on_middleman_model_.py +0 -0
  230. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/db/alembic/versions/73b04dca7c10_merge_heads_cascade_deletes_enable_rls.py +0 -0
  231. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/db/alembic/versions/77cdf99dcd0d_add_pg_trgm_indexes.py +0 -0
  232. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/db/alembic/versions/7f3caddc67ed_add_branch_and_anchor_event_columns.py +0 -0
  233. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/db/alembic/versions/86cfe97fc6d6_grant_rls_function_execute.py +0 -0
  234. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/db/alembic/versions/88abdab61a5d_sample_last_imported.py +0 -0
  235. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/db/alembic/versions/8b4908438916_merge_cost_limit_tracking_and_human_.py +0 -0
  236. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/db/alembic/versions/8c6950acaca1_merge_migration_heads.py +0 -0
  237. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/db/alembic/versions/9236fa4b5bb2_eval_set_id.py +0 -0
  238. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/db/alembic/versions/937673252d1e_add_message_pool_earliest_event_order.py +0 -0
  239. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/db/alembic/versions/950128797e52_add_job_deleted_at.py +0 -0
  240. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/db/alembic/versions/9a8a68ffa612_add_sample_invalidation_fields.py +0 -0
  241. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/db/alembic/versions/a1b2c3d4e5f6_rename_sample_ids.py +0 -0
  242. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/db/alembic/versions/a1b2c3d4e5f7_add_model_to_scan.py +0 -0
  243. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/db/alembic/versions/a1b2c3d4e5f9_memoize_rls_access_checks.py +0 -0
  244. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/db/alembic/versions/a2b3c4d5e6f7_add_sample_id_btree_index.py +0 -0
  245. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/db/alembic/versions/a3b4c5d6e7f8_add_fulltext_search_tsv.py +0 -0
  246. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/db/alembic/versions/a4c1e8b2d7f3_add_eval_eval_set_id_import_status_index.py +0 -0
  247. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/db/alembic/versions/a7b8c9d0e1f2_scan_model_groups_unresolved_sentinel.py +0 -0
  248. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/db/alembic/versions/a7c9d2e4f6b8_add_model_roles_tables.py +0 -0
  249. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/db/alembic/versions/a80826a7dd7d_add_approval_metadata_to_event.py +0 -0
  250. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/db/alembic/versions/b0c1d2e3f4a5_search_all_drop_model_call_pool.py +0 -0
  251. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/db/alembic/versions/b2c3d4e5f6a0_revert_rls_memoization.py +0 -0
  252. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/db/alembic/versions/b2c3d4e5f6a8_add_sample_search_text.py +0 -0
  253. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/db/alembic/versions/b3f7c9a1d2e4_add_event_sample_pk_event_type_index.py +0 -0
  254. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/db/alembic/versions/b4c5d6e7f8a9_cap_search_tsv_jsonb_columns.py +0 -0
  255. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/db/alembic/versions/b7f2c1a4e9d3_search_event_approval_metadata.py +0 -0
  256. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/db/alembic/versions/c1d2e3f4a5b6_add_model_group_mapping.py +0 -0
  257. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/db/alembic/versions/c3d4e5f6a7b8_search_event_model_output.py +0 -0
  258. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/db/alembic/versions/c3d4e5f6a7b9_token_limit_bigint.py +0 -0
  259. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/db/alembic/versions/c4d5e6f7a8b9_denormalize_model_groups.py +0 -0
  260. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/db/alembic/versions/c5d6e7f8a9b0_add_sample_search_indexes.py +0 -0
  261. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/db/alembic/versions/c7d8e9f0a1b2_match_canonical_model_names.py +0 -0
  262. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/db/alembic/versions/c8b3a2e1f4d5_add_completed_at_eval_pk_index.py +0 -0
  263. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/db/alembic/versions/c8d1e2f3a4b5_job_type_enum_to_hyphen.py +0 -0
  264. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/db/alembic/versions/ccfec570758e_merge_heads.py +0 -0
  265. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/db/alembic/versions/cd456ad85d24_scored_at.py +0 -0
  266. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/db/alembic/versions/d1e2f3a4b5c6_add_parallel_query_indexes.py +0 -0
  267. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/db/alembic/versions/d2e3f4a5b6c7_add_rls_infrastructure.py +0 -0
  268. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/db/alembic/versions/d4e5f6a7b8c9_harden_search_tsv_trigger_overflow.py +0 -0
  269. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/db/alembic/versions/d5e6f7a8b9c0_add_gin_index_on_eval_model_groups.py +0 -0
  270. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/db/alembic/versions/d6e7f8a9b0c1_search_all_websearch_tsquery.py +0 -0
  271. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/db/alembic/versions/d9e0f1a2b3c4_merge_unresolved_sentinel_and_completed_at_index.py +0 -0
  272. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/db/alembic/versions/e2f3a4b5c6d7_add_score_scored_at.py +0 -0
  273. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/db/alembic/versions/e38febbbfd76_score_final_scores_index.py +0 -0
  274. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/db/alembic/versions/e3f4a5b6c7d8_enable_rls.py +0 -0
  275. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/db/alembic/versions/e54f61f05480_refresh_model_groups_on_sample_transfer.py +0 -0
  276. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/db/alembic/versions/e5f6a7b8c9d0_defer_scan_model_groups_trigger.py +0 -0
  277. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/db/alembic/versions/e6f7a8b9c0d1_denormalize_scan_model_groups.py +0 -0
  278. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/db/alembic/versions/e7f8a9b0c1d2_search_all_recency_sort.py +0 -0
  279. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/db/alembic/versions/e83e6089a761_add_task_version_trigram_index.py +0 -0
  280. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/db/alembic/versions/e9a523a87aeb_add_human_table.py +0 -0
  281. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/db/alembic/versions/e9f1a2b3c4d5_add_model_role_type.py +0 -0
  282. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/db/alembic/versions/ecf5fbecb879_add_human_eval_assignment_table.py +0 -0
  283. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/db/alembic/versions/f0a1b2c3d4e5_add_scan_import_status.py +0 -0
  284. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/db/alembic/versions/f3a4b5c6d7e8_add_score_model_usage.py +0 -0
  285. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/db/alembic/versions/f8a9b0c1d2e3_search_all_scope_pushdown.py +0 -0
  286. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/db/alembic/versions/fb819443bf37_rm_is_complete.py +0 -0
  287. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/db/alembic/versions/fdee9bee9bf8_scans.py +0 -0
  288. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/db/backfill_earliest_event_order.py +0 -0
  289. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/db/backfill_search_tsv.py +0 -0
  290. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/db/connection.py +0 -0
  291. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/db/job_writes.py +0 -0
  292. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/db/models.py +0 -0
  293. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/db/parallel.py +0 -0
  294. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/db/serialization.py +0 -0
  295. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/db/upsert.py +0 -0
  296. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/dependencies.py +0 -0
  297. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/envsubst.py +0 -0
  298. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/eval_header.py +0 -0
  299. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/exceptions.py +0 -0
  300. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/importer/__init__.py +0 -0
  301. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/importer/eval/__init__.py +0 -0
  302. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/importer/eval/attachment_resolver.py +0 -0
  303. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/importer/eval/converter.py +0 -0
  304. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/importer/eval/externalization.py +0 -0
  305. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/importer/eval/importer.py +0 -0
  306. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/importer/eval/models.py +0 -0
  307. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/importer/eval/records.py +0 -0
  308. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/importer/eval/utils.py +0 -0
  309. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/importer/eval/writer/__init__.py +0 -0
  310. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/importer/eval/writers.py +0 -0
  311. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/importer/scan/__init__.py +0 -0
  312. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/importer/scan/importer.py +0 -0
  313. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/importer/scan/writer/__init__.py +0 -0
  314. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/importer/scan/writer/postgres.py +0 -0
  315. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/importer/writer.py +0 -0
  316. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/k8s_labels.py +0 -0
  317. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/logging.py +0 -0
  318. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/model_access.py +0 -0
  319. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/monitoring/__init__.py +0 -0
  320. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/monitoring/base.py +0 -0
  321. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/monitoring/eval_status.py +0 -0
  322. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/monitoring/kubernetes.py +0 -0
  323. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/providers.py +0 -0
  324. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/rate_limits/__init__.py +0 -0
  325. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/rate_limits/snapshots.py +0 -0
  326. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/rate_limits/usage.py +0 -0
  327. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/run_in_venv.py +0 -0
  328. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/sanitize.py +0 -0
  329. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/scan_filter.py +0 -0
  330. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/scan_parquet_guard.py +0 -0
  331. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/scan_spec_header.py +0 -0
  332. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/search/__init__.py +0 -0
  333. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/search/backend.py +0 -0
  334. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/search/postgres.py +0 -0
  335. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/search/service.py +0 -0
  336. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/search/transcript_grep.py +0 -0
  337. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/search/types.py +0 -0
  338. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/sse.py +0 -0
  339. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/tracing.py +0 -0
  340. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/types/__main__.py +0 -0
  341. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/types/artifacts.py +0 -0
  342. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/types/base.py +0 -0
  343. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/types/client_config.py +0 -0
  344. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/types/monitoring.py +0 -0
  345. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/types/sample_edit.py +0 -0
  346. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/types/scans.py +0 -0
  347. {hawk-3.2.0 → hawk-3.3.0}/hawk/core/version.py +0 -0
  348. {hawk-3.2.0 → hawk-3.3.0}/hawk/e2e/__init__.py +0 -0
  349. {hawk-3.2.0 → hawk-3.3.0}/hawk/e2e/task.py +0 -0
  350. {hawk-3.2.0 → hawk-3.3.0}/hawk/janitor/__init__.py +0 -0
  351. {hawk-3.2.0 → hawk-3.3.0}/hawk/janitor/__main__.py +0 -0
  352. {hawk-3.2.0 → hawk-3.3.0}/hawk/py.typed +0 -0
  353. {hawk-3.2.0 → hawk-3.3.0}/hawk/runner/__init__.py +0 -0
  354. {hawk-3.2.0 → hawk-3.3.0}/hawk/runner/approval_timeout.py +0 -0
  355. {hawk-3.2.0 → hawk-3.3.0}/hawk/runner/cloudwatch_metrics.py +0 -0
  356. {hawk-3.2.0 → hawk-3.3.0}/hawk/runner/datadog_dashboard.json +0 -0
  357. {hawk-3.2.0 → hawk-3.3.0}/hawk/runner/datadog_metrics.py +0 -0
  358. {hawk-3.2.0 → hawk-3.3.0}/hawk/runner/entrypoint.py +0 -0
  359. {hawk-3.2.0 → hawk-3.3.0}/hawk/runner/eval_set_surface.py +0 -0
  360. {hawk-3.2.0 → hawk-3.3.0}/hawk/runner/lifecycle.py +0 -0
  361. {hawk-3.2.0 → hawk-3.3.0}/hawk/runner/memory_monitor.py +0 -0
  362. {hawk-3.2.0 → hawk-3.3.0}/hawk/runner/oauth_errors.py +0 -0
  363. {hawk-3.2.0 → hawk-3.3.0}/hawk/runner/observability_headers.py +0 -0
  364. {hawk-3.2.0 → hawk-3.3.0}/hawk/runner/oom_diagnostics.py +0 -0
  365. {hawk-3.2.0 → hawk-3.3.0}/hawk/runner/otel_tracing.py +0 -0
  366. {hawk-3.2.0 → hawk-3.3.0}/hawk/runner/prior_attempt.py +0 -0
  367. {hawk-3.2.0 → hawk-3.3.0}/hawk/runner/process_tree.py +0 -0
  368. {hawk-3.2.0 → hawk-3.3.0}/hawk/runner/ptrace.py +0 -0
  369. {hawk-3.2.0 → hawk-3.3.0}/hawk/runner/refresh_token.py +0 -0
  370. {hawk-3.2.0 → hawk-3.3.0}/hawk/runner/refresh_token_override.py +0 -0
  371. {hawk-3.2.0 → hawk-3.3.0}/hawk/runner/run_scan.py +0 -0
  372. {hawk-3.2.0 → hawk-3.3.0}/hawk/runner/run_scan_resume.py +0 -0
  373. {hawk-3.2.0 → hawk-3.3.0}/hawk/runner/sandbox_concurrency.py +0 -0
  374. {hawk-3.2.0 → hawk-3.3.0}/hawk/runner/secrets.py +0 -0
  375. {hawk-3.2.0 → hawk-3.3.0}/hawk/runner/set_memory_high.py +0 -0
  376. {hawk-3.2.0 → hawk-3.3.0}/hawk/runner/setup_tracing.py +0 -0
  377. {hawk-3.2.0 → hawk-3.3.0}/hawk/runner/stop_monitor.py +0 -0
  378. {hawk-3.2.0 → hawk-3.3.0}/hawk/runner/stuck_eval_monitor.py +0 -0
  379. {hawk-3.2.0 → hawk-3.3.0}/hawk/runner/waiting_for_interaction.py +0 -0
  380. {hawk-3.2.0 → hawk-3.3.0}/hawk/tools/__init__.py +0 -0
  381. {hawk-3.2.0 → hawk-3.3.0}/hawk/tools/sync_models.py +0 -0
  382. {hawk-3.2.0 → hawk-3.3.0}/services/modules/eval_log_importer/eval_log_importer/__init__.py +0 -0
  383. {hawk-3.2.0 → hawk-3.3.0}/services/modules/eval_log_importer/eval_log_importer/__main__.py +0 -0
  384. {hawk-3.2.0 → hawk-3.3.0}/services/modules/eval_log_importer/pyproject.toml +0 -0
  385. {hawk-3.2.0 → hawk-3.3.0}/services/modules/eval_log_importer/tests/__init__.py +0 -0
  386. {hawk-3.2.0 → hawk-3.3.0}/services/modules/eval_log_importer/tests/test_main.py +0 -0
  387. {hawk-3.2.0 → hawk-3.3.0}/services/modules/eval_log_reader/README.md +0 -0
  388. {hawk-3.2.0 → hawk-3.3.0}/services/modules/eval_log_reader/eval_log_reader/__init__.py +0 -0
  389. {hawk-3.2.0 → hawk-3.3.0}/services/modules/eval_log_reader/eval_log_reader/index.py +0 -0
  390. {hawk-3.2.0 → hawk-3.3.0}/services/modules/eval_log_reader/pyproject.toml +0 -0
  391. {hawk-3.2.0 → hawk-3.3.0}/services/modules/eval_log_reader/tests/test_eval_log_reader.py +0 -0
  392. {hawk-3.2.0 → hawk-3.3.0}/services/modules/job_status_updated/job_status_updated/__init__.py +0 -0
  393. {hawk-3.2.0 → hawk-3.3.0}/services/modules/job_status_updated/job_status_updated/aws_clients.py +0 -0
  394. {hawk-3.2.0 → hawk-3.3.0}/services/modules/job_status_updated/job_status_updated/index.py +0 -0
  395. {hawk-3.2.0 → hawk-3.3.0}/services/modules/job_status_updated/job_status_updated/models.py +0 -0
  396. {hawk-3.2.0 → hawk-3.3.0}/services/modules/job_status_updated/job_status_updated/processors/__init__.py +0 -0
  397. {hawk-3.2.0 → hawk-3.3.0}/services/modules/job_status_updated/job_status_updated/processors/common.py +0 -0
  398. {hawk-3.2.0 → hawk-3.3.0}/services/modules/job_status_updated/job_status_updated/processors/eval.py +0 -0
  399. {hawk-3.2.0 → hawk-3.3.0}/services/modules/job_status_updated/job_status_updated/processors/scan.py +0 -0
  400. {hawk-3.2.0 → hawk-3.3.0}/services/modules/job_status_updated/pyproject.toml +0 -0
  401. {hawk-3.2.0 → hawk-3.3.0}/services/modules/job_status_updated/tests/__init__.py +0 -0
  402. {hawk-3.2.0 → hawk-3.3.0}/services/modules/job_status_updated/tests/conftest.py +0 -0
  403. {hawk-3.2.0 → hawk-3.3.0}/services/modules/job_status_updated/tests/test_common.py +0 -0
  404. {hawk-3.2.0 → hawk-3.3.0}/services/modules/job_status_updated/tests/test_eval_processor.py +0 -0
  405. {hawk-3.2.0 → hawk-3.3.0}/services/modules/job_status_updated/tests/test_routing.py +0 -0
  406. {hawk-3.2.0 → hawk-3.3.0}/services/modules/job_status_updated/tests/test_scan_processor.py +0 -0
  407. {hawk-3.2.0 → hawk-3.3.0}/services/modules/sample_editor/pyproject.toml +0 -0
  408. {hawk-3.2.0 → hawk-3.3.0}/services/modules/sample_editor/sample_editor/__init__.py +0 -0
  409. {hawk-3.2.0 → hawk-3.3.0}/services/modules/sample_editor/sample_editor/__main__.py +0 -0
  410. {hawk-3.2.0 → hawk-3.3.0}/services/modules/sample_editor/sample_editor/edit_sample.py +0 -0
  411. {hawk-3.2.0 → hawk-3.3.0}/services/modules/sample_editor/sample_editor/s3_conditional.py +0 -0
  412. {hawk-3.2.0 → hawk-3.3.0}/services/modules/sample_editor/tests/__init__.py +0 -0
  413. {hawk-3.2.0 → hawk-3.3.0}/services/modules/sample_editor/tests/conftest.py +0 -0
  414. {hawk-3.2.0 → hawk-3.3.0}/services/modules/sample_editor/tests/test_edit_sample.py +0 -0
  415. {hawk-3.2.0 → hawk-3.3.0}/services/modules/sample_editor/tests/test_main.py +0 -0
  416. {hawk-3.2.0 → hawk-3.3.0}/services/modules/sample_editor/tests/test_s3_conditional.py +0 -0
  417. {hawk-3.2.0 → hawk-3.3.0}/services/modules/scan_importer/pyproject.toml +0 -0
  418. {hawk-3.2.0 → hawk-3.3.0}/services/modules/scan_importer/scan_importer/index.py +0 -0
  419. {hawk-3.2.0 → hawk-3.3.0}/services/modules/scan_importer/tests/conftest.py +0 -0
  420. {hawk-3.2.0 → hawk-3.3.0}/services/modules/scan_importer/tests/test_index.py +0 -0
  421. {hawk-3.2.0 → hawk-3.3.0}/services/modules/token_broker/pyproject.toml +0 -0
  422. {hawk-3.2.0 → hawk-3.3.0}/services/modules/token_broker/tests/__init__.py +0 -0
  423. {hawk-3.2.0 → hawk-3.3.0}/services/modules/token_broker/tests/conftest.py +0 -0
  424. {hawk-3.2.0 → hawk-3.3.0}/services/modules/token_broker/tests/test_models.py +0 -0
  425. {hawk-3.2.0 → hawk-3.3.0}/services/modules/token_broker/tests/test_policy.py +0 -0
  426. {hawk-3.2.0 → hawk-3.3.0}/services/modules/token_broker/token_broker/__init__.py +0 -0
  427. {hawk-3.2.0 → hawk-3.3.0}/services/modules/token_broker/token_broker/policy.py +0 -0
  428. {hawk-3.2.0 → hawk-3.3.0}/services/modules/viewer/Dockerfile +0 -0
  429. {hawk-3.2.0 → hawk-3.3.0}/services/modules/viewer/nginx.conf +0 -0
  430. {hawk-3.2.0 → hawk-3.3.0}/tests/AGENTS.md +0 -0
  431. {hawk-3.2.0 → hawk-3.3.0}/tests/CLAUDE.md +0 -0
  432. {hawk-3.2.0 → hawk-3.3.0}/tests/README.md +0 -0
  433. {hawk-3.2.0 → hawk-3.3.0}/tests/__init__.py +0 -0
  434. {hawk-3.2.0 → hawk-3.3.0}/tests/api/__init__.py +0 -0
  435. {hawk-3.2.0 → hawk-3.3.0}/tests/api/auth/__init__.py +0 -0
  436. {hawk-3.2.0 → hawk-3.3.0}/tests/api/auth/test_access_token.py +0 -0
  437. {hawk-3.2.0 → hawk-3.3.0}/tests/api/auth/test_auth.py +0 -0
  438. {hawk-3.2.0 → hawk-3.3.0}/tests/api/auth/test_eval_log_permission_checker.py +0 -0
  439. {hawk-3.2.0 → hawk-3.3.0}/tests/api/auth/test_job_auth.py +0 -0
  440. {hawk-3.2.0 → hawk-3.3.0}/tests/api/auth/test_middleman_client.py +0 -0
  441. {hawk-3.2.0 → hawk-3.3.0}/tests/api/auth/test_permissions.py +0 -0
  442. {hawk-3.2.0 → hawk-3.3.0}/tests/api/auth/test_read_only.py +0 -0
  443. {hawk-3.2.0 → hawk-3.3.0}/tests/api/auth/test_s3_files.py +0 -0
  444. {hawk-3.2.0 → hawk-3.3.0}/tests/api/conftest.py +0 -0
  445. {hawk-3.2.0 → hawk-3.3.0}/tests/api/fake_redis.py +0 -0
  446. {hawk-3.2.0 → hawk-3.3.0}/tests/api/test_access_logging.py +0 -0
  447. {hawk-3.2.0 → hawk-3.3.0}/tests/api/test_auth_router.py +0 -0
  448. {hawk-3.2.0 → hawk-3.3.0}/tests/api/test_aws_secret_arns.py +0 -0
  449. {hawk-3.2.0 → hawk-3.3.0}/tests/api/test_cors.py +0 -0
  450. {hawk-3.2.0 → hawk-3.3.0}/tests/api/test_create_eval_set.py +0 -0
  451. {hawk-3.2.0 → hawk-3.3.0}/tests/api/test_create_scan.py +0 -0
  452. {hawk-3.2.0 → hawk-3.3.0}/tests/api/test_cross_lab.py +0 -0
  453. {hawk-3.2.0 → hawk-3.3.0}/tests/api/test_datadog_monitors.py +0 -0
  454. {hawk-3.2.0 → hawk-3.3.0}/tests/api/test_db_session_dep.py +0 -0
  455. {hawk-3.2.0 → hawk-3.3.0}/tests/api/test_delete_eval_set.py +0 -0
  456. {hawk-3.2.0 → hawk-3.3.0}/tests/api/test_delete_scan_run.py +0 -0
  457. {hawk-3.2.0 → hawk-3.3.0}/tests/api/test_eval_log_server.py +0 -0
  458. {hawk-3.2.0 → hawk-3.3.0}/tests/api/test_eval_set_config_endpoint.py +0 -0
  459. {hawk-3.2.0 → hawk-3.3.0}/tests/api/test_eval_set_resume.py +0 -0
  460. {hawk-3.2.0 → hawk-3.3.0}/tests/api/test_eval_set_secrets_validation.py +0 -0
  461. {hawk-3.2.0 → hawk-3.3.0}/tests/api/test_eval_sets_endpoint.py +0 -0
  462. {hawk-3.2.0 → hawk-3.3.0}/tests/api/test_evals_endpoint.py +0 -0
  463. {hawk-3.2.0 → hawk-3.3.0}/tests/api/test_event_serialization.py +0 -0
  464. {hawk-3.2.0 → hawk-3.3.0}/tests/api/test_health.py +0 -0
  465. {hawk-3.2.0 → hawk-3.3.0}/tests/api/test_health_endpoints.py +0 -0
  466. {hawk-3.2.0 → hawk-3.3.0}/tests/api/test_human_server.py +0 -0
  467. {hawk-3.2.0 → hawk-3.3.0}/tests/api/test_import_common.py +0 -0
  468. {hawk-3.2.0 → hawk-3.3.0}/tests/api/test_import_server.py +0 -0
  469. {hawk-3.2.0 → hawk-3.3.0}/tests/api/test_inspect_async_fs.py +0 -0
  470. {hawk-3.2.0 → hawk-3.3.0}/tests/api/test_job_template_architecture.py +0 -0
  471. {hawk-3.2.0 → hawk-3.3.0}/tests/api/test_job_template_http_defaults.py +0 -0
  472. {hawk-3.2.0 → hawk-3.3.0}/tests/api/test_job_template_token.py +0 -0
  473. {hawk-3.2.0 → hawk-3.3.0}/tests/api/test_jobs_endpoint.py +0 -0
  474. {hawk-3.2.0 → hawk-3.3.0}/tests/api/test_jobs_status.py +0 -0
  475. {hawk-3.2.0 → hawk-3.3.0}/tests/api/test_jumphost.py +0 -0
  476. {hawk-3.2.0 → hawk-3.3.0}/tests/api/test_meta_server_queries.py +0 -0
  477. {hawk-3.2.0 → hawk-3.3.0}/tests/api/test_monitoring_server.py +0 -0
  478. {hawk-3.2.0 → hawk-3.3.0}/tests/api/test_online_scan_create.py +0 -0
  479. {hawk-3.2.0 → hawk-3.3.0}/tests/api/test_otel_tracing.py +0 -0
  480. {hawk-3.2.0 → hawk-3.3.0}/tests/api/test_platform_metrics.py +0 -0
  481. {hawk-3.2.0 → hawk-3.3.0}/tests/api/test_presigned_urls.py +0 -0
  482. {hawk-3.2.0 → hawk-3.3.0}/tests/api/test_problem.py +0 -0
  483. {hawk-3.2.0 → hawk-3.3.0}/tests/api/test_provider_sdk_floors.py +0 -0
  484. {hawk-3.2.0 → hawk-3.3.0}/tests/api/test_run.py +0 -0
  485. {hawk-3.2.0 → hawk-3.3.0}/tests/api/test_run_cpu_request.py +0 -0
  486. {hawk-3.2.0 → hawk-3.3.0}/tests/api/test_run_job_secrets.py +0 -0
  487. {hawk-3.2.0 → hawk-3.3.0}/tests/api/test_run_memory_high.py +0 -0
  488. {hawk-3.2.0 → hawk-3.3.0}/tests/api/test_run_memory_request.py +0 -0
  489. {hawk-3.2.0 → hawk-3.3.0}/tests/api/test_sample_content_router.py +0 -0
  490. {hawk-3.2.0 → hawk-3.3.0}/tests/api/test_sample_edit_router.py +0 -0
  491. {hawk-3.2.0 → hawk-3.3.0}/tests/api/test_sample_events.py +0 -0
  492. {hawk-3.2.0 → hawk-3.3.0}/tests/api/test_sample_meta.py +0 -0
  493. {hawk-3.2.0 → hawk-3.3.0}/tests/api/test_sample_scores.py +0 -0
  494. {hawk-3.2.0 → hawk-3.3.0}/tests/api/test_samples_endpoint.py +0 -0
  495. {hawk-3.2.0 → hawk-3.3.0}/tests/api/test_scan_import_server.py +0 -0
  496. {hawk-3.2.0 → hawk-3.3.0}/tests/api/test_scan_secrets_validation.py +0 -0
  497. {hawk-3.2.0 → hawk-3.3.0}/tests/api/test_scan_server_unit.py +0 -0
  498. {hawk-3.2.0 → hawk-3.3.0}/tests/api/test_scan_subcommands.py +0 -0
  499. {hawk-3.2.0 → hawk-3.3.0}/tests/api/test_scan_view_server.py +0 -0
  500. {hawk-3.2.0 → hawk-3.3.0}/tests/api/test_scans_endpoint.py +0 -0
  501. {hawk-3.2.0 → hawk-3.3.0}/tests/api/test_schema_endpoint.py +0 -0
  502. {hawk-3.2.0 → hawk-3.3.0}/tests/api/test_search_sort_contract.py +0 -0
  503. {hawk-3.2.0 → hawk-3.3.0}/tests/api/test_server_before_send.py +0 -0
  504. {hawk-3.2.0 → hawk-3.3.0}/tests/api/test_server_policies.py +0 -0
  505. {hawk-3.2.0 → hawk-3.3.0}/tests/api/test_settings.py +0 -0
  506. {hawk-3.2.0 → hawk-3.3.0}/tests/api/test_stop_eval_set.py +0 -0
  507. {hawk-3.2.0 → hawk-3.3.0}/tests/api/test_timeline.py +0 -0
  508. {hawk-3.2.0 → hawk-3.3.0}/tests/api/test_transcript_search.py +0 -0
  509. {hawk-3.2.0 → hawk-3.3.0}/tests/api/test_transcript_search_cache.py +0 -0
  510. {hawk-3.2.0 → hawk-3.3.0}/tests/api/test_usage_server.py +0 -0
  511. {hawk-3.2.0 → hawk-3.3.0}/tests/api/test_validation.py +0 -0
  512. {hawk-3.2.0 → hawk-3.3.0}/tests/api/test_version_endpoint.py +0 -0
  513. {hawk-3.2.0 → hawk-3.3.0}/tests/api/test_yaml_safety.py +0 -0
  514. {hawk-3.2.0 → hawk-3.3.0}/tests/api/util/__init__.py +0 -0
  515. {hawk-3.2.0 → hawk-3.3.0}/tests/api/util/test_aiohttp_to_starlette.py +0 -0
  516. {hawk-3.2.0 → hawk-3.3.0}/tests/api/util/test_namespace.py +0 -0
  517. {hawk-3.2.0 → hawk-3.3.0}/tests/cli/__init__.py +0 -0
  518. {hawk-3.2.0 → hawk-3.3.0}/tests/cli/conftest.py +0 -0
  519. {hawk-3.2.0 → hawk-3.3.0}/tests/cli/seed/__init__.py +0 -0
  520. {hawk-3.2.0 → hawk-3.3.0}/tests/cli/seed/test_factories.py +0 -0
  521. {hawk-3.2.0 → hawk-3.3.0}/tests/cli/test_acp.py +0 -0
  522. {hawk-3.2.0 → hawk-3.3.0}/tests/cli/test_auth_commands.py +0 -0
  523. {hawk-3.2.0 → hawk-3.3.0}/tests/cli/test_cli.py +0 -0
  524. {hawk-3.2.0 → hawk-3.3.0}/tests/cli/test_config.py +0 -0
  525. {hawk-3.2.0 → hawk-3.3.0}/tests/cli/test_delete.py +0 -0
  526. {hawk-3.2.0 → hawk-3.3.0}/tests/cli/test_download.py +0 -0
  527. {hawk-3.2.0 → hawk-3.3.0}/tests/cli/test_download_artifacts.py +0 -0
  528. {hawk-3.2.0 → hawk-3.3.0}/tests/cli/test_edit_samples.py +0 -0
  529. {hawk-3.2.0 → hawk-3.3.0}/tests/cli/test_eval_set.py +0 -0
  530. {hawk-3.2.0 → hawk-3.3.0}/tests/cli/test_eval_set_subcommands.py +0 -0
  531. {hawk-3.2.0 → hawk-3.3.0}/tests/cli/test_human.py +0 -0
  532. {hawk-3.2.0 → hawk-3.3.0}/tests/cli/test_human_eval.py +0 -0
  533. {hawk-3.2.0 → hawk-3.3.0}/tests/cli/test_import_cmd.py +0 -0
  534. {hawk-3.2.0 → hawk-3.3.0}/tests/cli/test_import_upload.py +0 -0
  535. {hawk-3.2.0 → hawk-3.3.0}/tests/cli/test_list.py +0 -0
  536. {hawk-3.2.0 → hawk-3.3.0}/tests/cli/test_list_jobs.py +0 -0
  537. {hawk-3.2.0 → hawk-3.3.0}/tests/cli/test_local.py +0 -0
  538. {hawk-3.2.0 → hawk-3.3.0}/tests/cli/test_login.py +0 -0
  539. {hawk-3.2.0 → hawk-3.3.0}/tests/cli/test_models.py +0 -0
  540. {hawk-3.2.0 → hawk-3.3.0}/tests/cli/test_monitoring.py +0 -0
  541. {hawk-3.2.0 → hawk-3.3.0}/tests/cli/test_scan_export.py +0 -0
  542. {hawk-3.2.0 → hawk-3.3.0}/tests/cli/test_scan_import.py +0 -0
  543. {hawk-3.2.0 → hawk-3.3.0}/tests/cli/test_scan_subcommands.py +0 -0
  544. {hawk-3.2.0 → hawk-3.3.0}/tests/cli/test_seed.py +0 -0
  545. {hawk-3.2.0 → hawk-3.3.0}/tests/cli/test_ssh_probe.py +0 -0
  546. {hawk-3.2.0 → hawk-3.3.0}/tests/cli/test_stacktrace_command.py +0 -0
  547. {hawk-3.2.0 → hawk-3.3.0}/tests/cli/test_stop.py +0 -0
  548. {hawk-3.2.0 → hawk-3.3.0}/tests/cli/test_tokens.py +0 -0
  549. {hawk-3.2.0 → hawk-3.3.0}/tests/cli/test_trace.py +0 -0
  550. {hawk-3.2.0 → hawk-3.3.0}/tests/cli/test_trace_command.py +0 -0
  551. {hawk-3.2.0 → hawk-3.3.0}/tests/cli/test_transcript.py +0 -0
  552. {hawk-3.2.0 → hawk-3.3.0}/tests/cli/test_usage.py +0 -0
  553. {hawk-3.2.0 → hawk-3.3.0}/tests/cli/test_version_check.py +0 -0
  554. {hawk-3.2.0 → hawk-3.3.0}/tests/cli/test_version_cmd.py +0 -0
  555. {hawk-3.2.0 → hawk-3.3.0}/tests/cli/test_watch.py +0 -0
  556. {hawk-3.2.0 → hawk-3.3.0}/tests/cli/util/__init__.py +0 -0
  557. {hawk-3.2.0 → hawk-3.3.0}/tests/cli/util/test_api.py +0 -0
  558. {hawk-3.2.0 → hawk-3.3.0}/tests/cli/util/test_auth.py +0 -0
  559. {hawk-3.2.0 → hawk-3.3.0}/tests/cli/util/test_auth_pkce.py +0 -0
  560. {hawk-3.2.0 → hawk-3.3.0}/tests/cli/util/test_responses.py +0 -0
  561. {hawk-3.2.0 → hawk-3.3.0}/tests/cli/util/test_secrets.py +0 -0
  562. {hawk-3.2.0 → hawk-3.3.0}/tests/cli/util/test_table.py +0 -0
  563. {hawk-3.2.0 → hawk-3.3.0}/tests/conftest.py +0 -0
  564. {hawk-3.2.0 → hawk-3.3.0}/tests/core/__init__.py +0 -0
  565. {hawk-3.2.0 → hawk-3.3.0}/tests/core/db/test_backfill_earliest_event_order.py +0 -0
  566. {hawk-3.2.0 → hawk-3.3.0}/tests/core/db/test_backfill_search_tsv.py +0 -0
  567. {hawk-3.2.0 → hawk-3.3.0}/tests/core/db/test_code.py +0 -0
  568. {hawk-3.2.0 → hawk-3.3.0}/tests/core/db/test_code_group.py +0 -0
  569. {hawk-3.2.0 → hawk-3.3.0}/tests/core/db/test_connection.py +0 -0
  570. {hawk-3.2.0 → hawk-3.3.0}/tests/core/db/test_event_column_types.py +0 -0
  571. {hawk-3.2.0 → hawk-3.3.0}/tests/core/db/test_functions.py +0 -0
  572. {hawk-3.2.0 → hawk-3.3.0}/tests/core/db/test_job_writes.py +0 -0
  573. {hawk-3.2.0 → hawk-3.3.0}/tests/core/db/test_model_group.py +0 -0
  574. {hawk-3.2.0 → hawk-3.3.0}/tests/core/db/test_model_groups_transfer.py +0 -0
  575. {hawk-3.2.0 → hawk-3.3.0}/tests/core/db/test_parallel.py +0 -0
  576. {hawk-3.2.0 → hawk-3.3.0}/tests/core/db/test_search.py +0 -0
  577. {hawk-3.2.0 → hawk-3.3.0}/tests/core/db/test_upsert.py +0 -0
  578. {hawk-3.2.0 → hawk-3.3.0}/tests/core/importer/__init__.py +0 -0
  579. {hawk-3.2.0 → hawk-3.3.0}/tests/core/importer/data_fixtures/eval_logs/small.eval +0 -0
  580. {hawk-3.2.0 → hawk-3.3.0}/tests/core/importer/eval/__init__.py +0 -0
  581. {hawk-3.2.0 → hawk-3.3.0}/tests/core/importer/eval/conftest.py +0 -0
  582. {hawk-3.2.0 → hawk-3.3.0}/tests/core/importer/eval/test_attachment_resolver.py +0 -0
  583. {hawk-3.2.0 → hawk-3.3.0}/tests/core/importer/eval/test_converter.py +0 -0
  584. {hawk-3.2.0 → hawk-3.3.0}/tests/core/importer/eval/test_converter_parity.py +0 -0
  585. {hawk-3.2.0 → hawk-3.3.0}/tests/core/importer/eval/test_externalization.py +0 -0
  586. {hawk-3.2.0 → hawk-3.3.0}/tests/core/importer/eval/test_importer.py +0 -0
  587. {hawk-3.2.0 → hawk-3.3.0}/tests/core/importer/eval/test_sample_owner_race.py +0 -0
  588. {hawk-3.2.0 → hawk-3.3.0}/tests/core/importer/eval/test_sanitization.py +0 -0
  589. {hawk-3.2.0 → hawk-3.3.0}/tests/core/importer/eval/test_utils.py +0 -0
  590. {hawk-3.2.0 → hawk-3.3.0}/tests/core/importer/eval/test_writers.py +0 -0
  591. {hawk-3.2.0 → hawk-3.3.0}/tests/core/importer/scan/__init__.py +0 -0
  592. {hawk-3.2.0 → hawk-3.3.0}/tests/core/importer/scan/conftest.py +0 -0
  593. {hawk-3.2.0 → hawk-3.3.0}/tests/core/importer/scan/test_idempotency.py +0 -0
  594. {hawk-3.2.0 → hawk-3.3.0}/tests/core/importer/scan/test_import_eval_log_scan.py +0 -0
  595. {hawk-3.2.0 → hawk-3.3.0}/tests/core/importer/scan/test_import_transcript_scan.py +0 -0
  596. {hawk-3.2.0 → hawk-3.3.0}/tests/core/importer/scan/test_viewer_columns_contract.py +0 -0
  597. {hawk-3.2.0 → hawk-3.3.0}/tests/core/importer/scan/test_writer_postgres.py +0 -0
  598. {hawk-3.2.0 → hawk-3.3.0}/tests/core/monitoring/__init__.py +0 -0
  599. {hawk-3.2.0 → hawk-3.3.0}/tests/core/monitoring/test_eval_status.py +0 -0
  600. {hawk-3.2.0 → hawk-3.3.0}/tests/core/monitoring/test_kubernetes.py +0 -0
  601. {hawk-3.2.0 → hawk-3.3.0}/tests/core/monitoring/test_monitoring.py +0 -0
  602. {hawk-3.2.0 → hawk-3.3.0}/tests/core/rate_limits/__init__.py +0 -0
  603. {hawk-3.2.0 → hawk-3.3.0}/tests/core/rate_limits/test_snapshots.py +0 -0
  604. {hawk-3.2.0 → hawk-3.3.0}/tests/core/rate_limits/test_usage.py +0 -0
  605. {hawk-3.2.0 → hawk-3.3.0}/tests/core/search/test_researcher_queries.py +0 -0
  606. {hawk-3.2.0 → hawk-3.3.0}/tests/core/search/test_service.py +0 -0
  607. {hawk-3.2.0 → hawk-3.3.0}/tests/core/search/test_transcript_grep.py +0 -0
  608. {hawk-3.2.0 → hawk-3.3.0}/tests/core/test_constants.py +0 -0
  609. {hawk-3.2.0 → hawk-3.3.0}/tests/core/test_dependencies.py +0 -0
  610. {hawk-3.2.0 → hawk-3.3.0}/tests/core/test_envsubst.py +0 -0
  611. {hawk-3.2.0 → hawk-3.3.0}/tests/core/test_eval_header.py +0 -0
  612. {hawk-3.2.0 → hawk-3.3.0}/tests/core/test_eval_logs_fixture.py +0 -0
  613. {hawk-3.2.0 → hawk-3.3.0}/tests/core/test_jwt_validator.py +0 -0
  614. {hawk-3.2.0 → hawk-3.3.0}/tests/core/test_model_access.py +0 -0
  615. {hawk-3.2.0 → hawk-3.3.0}/tests/core/test_providers.py +0 -0
  616. {hawk-3.2.0 → hawk-3.3.0}/tests/core/test_runner_config.py +0 -0
  617. {hawk-3.2.0 → hawk-3.3.0}/tests/core/test_sanitize.py +0 -0
  618. {hawk-3.2.0 → hawk-3.3.0}/tests/core/test_scan_parquet_guard.py +0 -0
  619. {hawk-3.2.0 → hawk-3.3.0}/tests/core/test_scans_types.py +0 -0
  620. {hawk-3.2.0 → hawk-3.3.0}/tests/core/test_sse.py +0 -0
  621. {hawk-3.2.0 → hawk-3.3.0}/tests/core/test_tracing.py +0 -0
  622. {hawk-3.2.0 → hawk-3.3.0}/tests/core/test_version.py +0 -0
  623. {hawk-3.2.0 → hawk-3.3.0}/tests/core/types/__init__.py +0 -0
  624. {hawk-3.2.0 → hawk-3.3.0}/tests/core/types/test_artifacts.py +0 -0
  625. {hawk-3.2.0 → hawk-3.3.0}/tests/core/types/test_base.py +0 -0
  626. {hawk-3.2.0 → hawk-3.3.0}/tests/core/types/test_lazy_imports.py +0 -0
  627. {hawk-3.2.0 → hawk-3.3.0}/tests/core/types/test_scans.py +0 -0
  628. {hawk-3.2.0 → hawk-3.3.0}/tests/fixtures/__init__.py +0 -0
  629. {hawk-3.2.0 → hawk-3.3.0}/tests/fixtures/converter_allowlist.py +0 -0
  630. {hawk-3.2.0 → hawk-3.3.0}/tests/fixtures/db.py +0 -0
  631. {hawk-3.2.0 → hawk-3.3.0}/tests/fixtures/environment.py +0 -0
  632. {hawk-3.2.0 → hawk-3.3.0}/tests/fixtures/eval_logs.py +0 -0
  633. {hawk-3.2.0 → hawk-3.3.0}/tests/fixtures/where.py +0 -0
  634. {hawk-3.2.0 → hawk-3.3.0}/tests/janitor/__init__.py +0 -0
  635. {hawk-3.2.0 → hawk-3.3.0}/tests/janitor/test_janitor.py +0 -0
  636. {hawk-3.2.0 → hawk-3.3.0}/tests/runner/__init__.py +0 -0
  637. {hawk-3.2.0 → hawk-3.3.0}/tests/runner/data_fixtures/eval_logs/2025-12-13T23-15-44+00-00_class-eval_XDtHXBaqEHGUBoFoinn2wS.eval +0 -0
  638. {hawk-3.2.0 → hawk-3.3.0}/tests/runner/data_fixtures/python-package/README.md +0 -0
  639. {hawk-3.2.0 → hawk-3.3.0}/tests/runner/data_fixtures/python-package/pyproject.toml +0 -0
  640. {hawk-3.2.0 → hawk-3.3.0}/tests/runner/data_fixtures/python-package/python_package/__init__.py +0 -0
  641. {hawk-3.2.0 → hawk-3.3.0}/tests/runner/data_fixtures/task/calculate_sum/__init__.py +0 -0
  642. {hawk-3.2.0 → hawk-3.3.0}/tests/runner/data_fixtures/task/calculate_sum/_registry.py +0 -0
  643. {hawk-3.2.0 → hawk-3.3.0}/tests/runner/data_fixtures/task/calculate_sum/task.py +0 -0
  644. {hawk-3.2.0 → hawk-3.3.0}/tests/runner/data_fixtures/task/pyproject.toml +0 -0
  645. {hawk-3.2.0 → hawk-3.3.0}/tests/runner/test_apply_config_defaults.py +0 -0
  646. {hawk-3.2.0 → hawk-3.3.0}/tests/runner/test_approval_invariants.py +0 -0
  647. {hawk-3.2.0 → hawk-3.3.0}/tests/runner/test_approval_timeout.py +0 -0
  648. {hawk-3.2.0 → hawk-3.3.0}/tests/runner/test_cloudwatch_metrics.py +0 -0
  649. {hawk-3.2.0 → hawk-3.3.0}/tests/runner/test_compose_file.py +0 -0
  650. {hawk-3.2.0 → hawk-3.3.0}/tests/runner/test_datadog_metrics.py +0 -0
  651. {hawk-3.2.0 → hawk-3.3.0}/tests/runner/test_entrypoint_secrets.py +0 -0
  652. {hawk-3.2.0 → hawk-3.3.0}/tests/runner/test_eval_set_config.py +0 -0
  653. {hawk-3.2.0 → hawk-3.3.0}/tests/runner/test_eval_set_forwardable_keys.py +0 -0
  654. {hawk-3.2.0 → hawk-3.3.0}/tests/runner/test_hook_full_sample_optout.py +0 -0
  655. {hawk-3.2.0 → hawk-3.3.0}/tests/runner/test_lifecycle.py +0 -0
  656. {hawk-3.2.0 → hawk-3.3.0}/tests/runner/test_logging.py +0 -0
  657. {hawk-3.2.0 → hawk-3.3.0}/tests/runner/test_memory_monitor.py +0 -0
  658. {hawk-3.2.0 → hawk-3.3.0}/tests/runner/test_observability_headers.py +0 -0
  659. {hawk-3.2.0 → hawk-3.3.0}/tests/runner/test_oom_diagnostics.py +0 -0
  660. {hawk-3.2.0 → hawk-3.3.0}/tests/runner/test_otel_tracing.py +0 -0
  661. {hawk-3.2.0 → hawk-3.3.0}/tests/runner/test_patch_sandbox_environments.py +0 -0
  662. {hawk-3.2.0 → hawk-3.3.0}/tests/runner/test_prior_attempt.py +0 -0
  663. {hawk-3.2.0 → hawk-3.3.0}/tests/runner/test_process_tree.py +0 -0
  664. {hawk-3.2.0 → hawk-3.3.0}/tests/runner/test_ptrace.py +0 -0
  665. {hawk-3.2.0 → hawk-3.3.0}/tests/runner/test_refresh_token.py +0 -0
  666. {hawk-3.2.0 → hawk-3.3.0}/tests/runner/test_refresh_token_override.py +0 -0
  667. {hawk-3.2.0 → hawk-3.3.0}/tests/runner/test_run_eval_set_oom_diagnostics.py +0 -0
  668. {hawk-3.2.0 → hawk-3.3.0}/tests/runner/test_run_scan.py +0 -0
  669. {hawk-3.2.0 → hawk-3.3.0}/tests/runner/test_run_scan_resume.py +0 -0
  670. {hawk-3.2.0 → hawk-3.3.0}/tests/runner/test_runner.py +0 -0
  671. {hawk-3.2.0 → hawk-3.3.0}/tests/runner/test_secrets.py +0 -0
  672. {hawk-3.2.0 → hawk-3.3.0}/tests/runner/test_set_memory_high.py +0 -0
  673. {hawk-3.2.0 → hawk-3.3.0}/tests/runner/test_setup_tracing.py +0 -0
  674. {hawk-3.2.0 → hawk-3.3.0}/tests/runner/test_smoke_discovery.py +0 -0
  675. {hawk-3.2.0 → hawk-3.3.0}/tests/runner/test_smoke_ecr_sync.py +0 -0
  676. {hawk-3.2.0 → hawk-3.3.0}/tests/runner/test_smoke_executor.py +0 -0
  677. {hawk-3.2.0 → hawk-3.3.0}/tests/runner/test_smoke_framework_env.py +0 -0
  678. {hawk-3.2.0 → hawk-3.3.0}/tests/runner/test_smoke_janitor.py +0 -0
  679. {hawk-3.2.0 → hawk-3.3.0}/tests/runner/test_smoke_main.py +0 -0
  680. {hawk-3.2.0 → hawk-3.3.0}/tests/runner/test_smoke_progress.py +0 -0
  681. {hawk-3.2.0 → hawk-3.3.0}/tests/runner/test_smoke_tui.py +0 -0
  682. {hawk-3.2.0 → hawk-3.3.0}/tests/runner/test_smoke_tui_app.py +0 -0
  683. {hawk-3.2.0 → hawk-3.3.0}/tests/runner/test_stop_monitor.py +0 -0
  684. {hawk-3.2.0 → hawk-3.3.0}/tests/runner/test_stuck_eval_monitor.py +0 -0
  685. {hawk-3.2.0 → hawk-3.3.0}/tests/runner/test_waiting_for_interaction.py +0 -0
  686. {hawk-3.2.0 → hawk-3.3.0}/tests/smoke/README.md +0 -0
  687. {hawk-3.2.0 → hawk-3.3.0}/tests/smoke/__init__.py +0 -0
  688. {hawk-3.2.0 → hawk-3.3.0}/tests/smoke/assets/fibonacci.broccoli +0 -0
  689. {hawk-3.2.0 → hawk-3.3.0}/tests/smoke/assets/fibonacci_bad.broccoli +0 -0
  690. {hawk-3.2.0 → hawk-3.3.0}/tests/smoke/conftest.py +0 -0
  691. {hawk-3.2.0 → hawk-3.3.0}/tests/smoke/eval_sets/complicated_task.yaml +0 -0
  692. {hawk-3.2.0 → hawk-3.3.0}/tests/smoke/eval_sets/configurable_sandbox.yaml +0 -0
  693. {hawk-3.2.0 → hawk-3.3.0}/tests/smoke/eval_sets/cost_tracking.yaml +0 -0
  694. {hawk-3.2.0 → hawk-3.3.0}/tests/smoke/eval_sets/env_capture_claude_code.yaml +0 -0
  695. {hawk-3.2.0 → hawk-3.3.0}/tests/smoke/eval_sets/env_capture_human.yaml +0 -0
  696. {hawk-3.2.0 → hawk-3.3.0}/tests/smoke/eval_sets/env_capture_react.yaml +0 -0
  697. {hawk-3.2.0 → hawk-3.3.0}/tests/smoke/eval_sets/fails_scoring.yaml +0 -0
  698. {hawk-3.2.0 → hawk-3.3.0}/tests/smoke/eval_sets/fails_setup.yaml +0 -0
  699. {hawk-3.2.0 → hawk-3.3.0}/tests/smoke/eval_sets/guess_number.yaml +0 -0
  700. {hawk-3.2.0 → hawk-3.3.0}/tests/smoke/eval_sets/gvisor_sandbox.yaml +0 -0
  701. {hawk-3.2.0 → hawk-3.3.0}/tests/smoke/eval_sets/human_baseline.yaml +0 -0
  702. {hawk-3.2.0 → hawk-3.3.0}/tests/smoke/eval_sets/manual_scoring.yaml +0 -0
  703. {hawk-3.2.0 → hawk-3.3.0}/tests/smoke/eval_sets/metr_agents_react.yaml +0 -0
  704. {hawk-3.2.0 → hawk-3.3.0}/tests/smoke/eval_sets/metr_agents_react_crash_resume.yaml +0 -0
  705. {hawk-3.2.0 → hawk-3.3.0}/tests/smoke/eval_sets/metr_agents_react_with_checkpoint_submit.yaml +0 -0
  706. {hawk-3.2.0 → hawk-3.3.0}/tests/smoke/eval_sets/metr_agents_react_with_gated_submit.yaml +0 -0
  707. {hawk-3.2.0 → hawk-3.3.0}/tests/smoke/eval_sets/model_roles.yaml +0 -0
  708. {hawk-3.2.0 → hawk-3.3.0}/tests/smoke/eval_sets/network_sandbox.yaml +0 -0
  709. {hawk-3.2.0 → hawk-3.3.0}/tests/smoke/eval_sets/network_sandbox_mixed.yaml +0 -0
  710. {hawk-3.2.0 → hawk-3.3.0}/tests/smoke/eval_sets/online_scan.yaml +0 -0
  711. {hawk-3.2.0 → hawk-3.3.0}/tests/smoke/eval_sets/real_llm.yaml +0 -0
  712. {hawk-3.2.0 → hawk-3.3.0}/tests/smoke/eval_sets/relay_acp.yaml +0 -0
  713. {hawk-3.2.0 → hawk-3.3.0}/tests/smoke/eval_sets/resume_probe.yaml +0 -0
  714. {hawk-3.2.0 → hawk-3.3.0}/tests/smoke/eval_sets/sample_eval_sets.py +0 -0
  715. {hawk-3.2.0 → hawk-3.3.0}/tests/smoke/eval_sets/say_hello.yaml +0 -0
  716. {hawk-3.2.0 → hawk-3.3.0}/tests/smoke/eval_sets/say_hello_with_tools.yaml +0 -0
  717. {hawk-3.2.0 → hawk-3.3.0}/tests/smoke/eval_sets/task_bridge.yaml +0 -0
  718. {hawk-3.2.0 → hawk-3.3.0}/tests/smoke/framework/__init__.py +0 -0
  719. {hawk-3.2.0 → hawk-3.3.0}/tests/smoke/framework/common.py +0 -0
  720. {hawk-3.2.0 → hawk-3.3.0}/tests/smoke/framework/context.py +0 -0
  721. {hawk-3.2.0 → hawk-3.3.0}/tests/smoke/framework/diagnostics.py +0 -0
  722. {hawk-3.2.0 → hawk-3.3.0}/tests/smoke/framework/ecr_sync.py +0 -0
  723. {hawk-3.2.0 → hawk-3.3.0}/tests/smoke/framework/edit_sample.py +0 -0
  724. {hawk-3.2.0 → hawk-3.3.0}/tests/smoke/framework/env.py +0 -0
  725. {hawk-3.2.0 → hawk-3.3.0}/tests/smoke/framework/env_capture.py +0 -0
  726. {hawk-3.2.0 → hawk-3.3.0}/tests/smoke/framework/env_compare.py +0 -0
  727. {hawk-3.2.0 → hawk-3.3.0}/tests/smoke/framework/eval_set_status.py +0 -0
  728. {hawk-3.2.0 → hawk-3.3.0}/tests/smoke/framework/eval_sets.py +0 -0
  729. {hawk-3.2.0 → hawk-3.3.0}/tests/smoke/framework/human.py +0 -0
  730. {hawk-3.2.0 → hawk-3.3.0}/tests/smoke/framework/human_baseline.py +0 -0
  731. {hawk-3.2.0 → hawk-3.3.0}/tests/smoke/framework/human_eval.py +0 -0
  732. {hawk-3.2.0 → hawk-3.3.0}/tests/smoke/framework/imports.py +0 -0
  733. {hawk-3.2.0 → hawk-3.3.0}/tests/smoke/framework/janitor.py +0 -0
  734. {hawk-3.2.0 → hawk-3.3.0}/tests/smoke/framework/logs.py +0 -0
  735. {hawk-3.2.0 → hawk-3.3.0}/tests/smoke/framework/manifests.py +0 -0
  736. {hawk-3.2.0 → hawk-3.3.0}/tests/smoke/framework/models.py +0 -0
  737. {hawk-3.2.0 → hawk-3.3.0}/tests/smoke/framework/preflight.py +0 -0
  738. {hawk-3.2.0 → hawk-3.3.0}/tests/smoke/framework/required_images.py +0 -0
  739. {hawk-3.2.0 → hawk-3.3.0}/tests/smoke/framework/s3.py +0 -0
  740. {hawk-3.2.0 → hawk-3.3.0}/tests/smoke/framework/scans.py +0 -0
  741. {hawk-3.2.0 → hawk-3.3.0}/tests/smoke/framework/tool_calls.py +0 -0
  742. {hawk-3.2.0 → hawk-3.3.0}/tests/smoke/framework/viewer.py +0 -0
  743. {hawk-3.2.0 → hawk-3.3.0}/tests/smoke/framework/warehouse.py +0 -0
  744. {hawk-3.2.0 → hawk-3.3.0}/tests/smoke/runner/__init__.py +0 -0
  745. {hawk-3.2.0 → hawk-3.3.0}/tests/smoke/runner/__main__.py +0 -0
  746. {hawk-3.2.0 → hawk-3.3.0}/tests/smoke/runner/discovery.py +0 -0
  747. {hawk-3.2.0 → hawk-3.3.0}/tests/smoke/runner/dump.py +0 -0
  748. {hawk-3.2.0 → hawk-3.3.0}/tests/smoke/runner/events.py +0 -0
  749. {hawk-3.2.0 → hawk-3.3.0}/tests/smoke/runner/executor.py +0 -0
  750. {hawk-3.2.0 → hawk-3.3.0}/tests/smoke/runner/progress.py +0 -0
  751. {hawk-3.2.0 → hawk-3.3.0}/tests/smoke/runner/textual_app.py +0 -0
  752. {hawk-3.2.0 → hawk-3.3.0}/tests/smoke/runner/widgets/__init__.py +0 -0
  753. {hawk-3.2.0 → hawk-3.3.0}/tests/smoke/runner/widgets/progress_header.py +0 -0
  754. {hawk-3.2.0 → hawk-3.3.0}/tests/smoke/runner/widgets/smoke_tree.py +0 -0
  755. {hawk-3.2.0 → hawk-3.3.0}/tests/smoke/runner/widgets/test_detail.py +0 -0
  756. {hawk-3.2.0 → hawk-3.3.0}/tests/smoke/scans/model_roles.yaml +0 -0
  757. {hawk-3.2.0 → hawk-3.3.0}/tests/smoke/scans/sample_scan_configs.py +0 -0
  758. {hawk-3.2.0 → hawk-3.3.0}/tests/smoke/scans/word_counter.yaml +0 -0
  759. {hawk-3.2.0 → hawk-3.3.0}/tests/smoke/scenarios/__init__.py +0 -0
  760. {hawk-3.2.0 → hawk-3.3.0}/tests/smoke/scenarios/test_checkpoint_resume.py +0 -0
  761. {hawk-3.2.0 → hawk-3.3.0}/tests/smoke/scenarios/test_custom_runner_image.py +0 -0
  762. {hawk-3.2.0 → hawk-3.3.0}/tests/smoke/scenarios/test_env_parity.py +0 -0
  763. {hawk-3.2.0 → hawk-3.3.0}/tests/smoke/scenarios/test_eval_set_status.py +0 -0
  764. {hawk-3.2.0 → hawk-3.3.0}/tests/smoke/scenarios/test_gpu.py +0 -0
  765. {hawk-3.2.0 → hawk-3.3.0}/tests/smoke/scenarios/test_gvisor.py +0 -0
  766. {hawk-3.2.0 → hawk-3.3.0}/tests/smoke/scenarios/test_human_baseline.py +0 -0
  767. {hawk-3.2.0 → hawk-3.3.0}/tests/smoke/scenarios/test_import.py +0 -0
  768. {hawk-3.2.0 → hawk-3.3.0}/tests/smoke/scenarios/test_internet_access.py +0 -0
  769. {hawk-3.2.0 → hawk-3.3.0}/tests/smoke/scenarios/test_isolation.py +0 -0
  770. {hawk-3.2.0 → hawk-3.3.0}/tests/smoke/scenarios/test_metr_agents.py +0 -0
  771. {hawk-3.2.0 → hawk-3.3.0}/tests/smoke/scenarios/test_middleman_anthropic_wif.py +0 -0
  772. {hawk-3.2.0 → hawk-3.3.0}/tests/smoke/scenarios/test_middleman_health.py +0 -0
  773. {hawk-3.2.0 → hawk-3.3.0}/tests/smoke/scenarios/test_middleman_models.py +0 -0
  774. {hawk-3.2.0 → hawk-3.3.0}/tests/smoke/scenarios/test_network_connectivity.py +0 -0
  775. {hawk-3.2.0 → hawk-3.3.0}/tests/smoke/scenarios/test_online_scan_gate_files.py +0 -0
  776. {hawk-3.2.0 → hawk-3.3.0}/tests/smoke/scenarios/test_otel_tracing.py +0 -0
  777. {hawk-3.2.0 → hawk-3.3.0}/tests/smoke/scenarios/test_outcomes.py +0 -0
  778. {hawk-3.2.0 → hawk-3.3.0}/tests/smoke/scenarios/test_pending_approvals.py +0 -0
  779. {hawk-3.2.0 → hawk-3.3.0}/tests/smoke/scenarios/test_real_llm.py +0 -0
  780. {hawk-3.2.0 → hawk-3.3.0}/tests/smoke/scenarios/test_relay.py +0 -0
  781. {hawk-3.2.0 → hawk-3.3.0}/tests/smoke/scenarios/test_sample_edit.py +0 -0
  782. {hawk-3.2.0 → hawk-3.3.0}/tests/smoke/scenarios/test_scan.py +0 -0
  783. {hawk-3.2.0 → hawk-3.3.0}/tests/smoke/scenarios/test_scan_import.py +0 -0
  784. {hawk-3.2.0 → hawk-3.3.0}/tests/smoke/scenarios/test_search_perf.py +0 -0
  785. {hawk-3.2.0 → hawk-3.3.0}/tests/smoke/scenarios/test_task_bridge.py +0 -0
  786. {hawk-3.2.0 → hawk-3.3.0}/tests/smoke/scenarios/test_tools.py +0 -0
  787. {hawk-3.2.0 → hawk-3.3.0}/tests/smoke/scenarios/test_transcript_search.py +0 -0
  788. {hawk-3.2.0 → hawk-3.3.0}/tests/smoke/scenarios/test_viewer_cookie_auth.py +0 -0
  789. {hawk-3.2.0 → hawk-3.3.0}/tests/smoke/test_middleman_admin_cli.py +0 -0
  790. {hawk-3.2.0 → hawk-3.3.0}/tests/smoke/test_middleman_admin_models.py +0 -0
  791. {hawk-3.2.0 → hawk-3.3.0}/tests/smoke/test_middleman_admin_secrets.py +0 -0
  792. {hawk-3.2.0 → hawk-3.3.0}/tests/test_e2e.py +0 -0
  793. {hawk-3.2.0 → hawk-3.3.0}/tests/test_smoke_diagnostics.py +0 -0
  794. {hawk-3.2.0 → hawk-3.3.0}/tests/util/__init__.py +0 -0
  795. {hawk-3.2.0 → hawk-3.3.0}/tests/util/test_configs.py +0 -0
  796. {hawk-3.2.0 → hawk-3.3.0}/www/.gitignore +0 -0
  797. {hawk-3.2.0 → hawk-3.3.0}/www/.prettierignore +0 -0
  798. {hawk-3.2.0 → hawk-3.3.0}/www/.prettierrc +0 -0
  799. {hawk-3.2.0 → hawk-3.3.0}/www/AGENTS.md +0 -0
  800. {hawk-3.2.0 → hawk-3.3.0}/www/CLAUDE.md +0 -0
  801. {hawk-3.2.0 → hawk-3.3.0}/www/README.md +0 -0
  802. {hawk-3.2.0 → hawk-3.3.0}/www/eslint.config.js +0 -0
  803. {hawk-3.2.0 → hawk-3.3.0}/www/index.html +0 -0
  804. {hawk-3.2.0 → hawk-3.3.0}/www/package.json +0 -0
  805. {hawk-3.2.0 → hawk-3.3.0}/www/pnpm-lock.yaml +0 -0
  806. {hawk-3.2.0 → hawk-3.3.0}/www/pnpm-workspace.yaml +0 -0
  807. {hawk-3.2.0 → hawk-3.3.0}/www/public/favicon.svg +0 -0
  808. {hawk-3.2.0 → hawk-3.3.0}/www/src/AppRouter.tsx +0 -0
  809. {hawk-3.2.0 → hawk-3.3.0}/www/src/EvalApp.tsx +0 -0
  810. {hawk-3.2.0 → hawk-3.3.0}/www/src/EvalPage.tsx +0 -0
  811. {hawk-3.2.0 → hawk-3.3.0}/www/src/EvalSetListPage.tsx +0 -0
  812. {hawk-3.2.0 → hawk-3.3.0}/www/src/JobsPage.tsx +0 -0
  813. {hawk-3.2.0 → hawk-3.3.0}/www/src/QueryProvider.tsx +0 -0
  814. {hawk-3.2.0 → hawk-3.3.0}/www/src/RateLimitsPage.tsx +0 -0
  815. {hawk-3.2.0 → hawk-3.3.0}/www/src/SamplesPage.tsx +0 -0
  816. {hawk-3.2.0 → hawk-3.3.0}/www/src/ScanApp.tsx +0 -0
  817. {hawk-3.2.0 → hawk-3.3.0}/www/src/ScanPage.tsx +0 -0
  818. {hawk-3.2.0 → hawk-3.3.0}/www/src/ScansPage.tsx +0 -0
  819. {hawk-3.2.0 → hawk-3.3.0}/www/src/TranscriptSearchPage.tsx +0 -0
  820. {hawk-3.2.0 → hawk-3.3.0}/www/src/browser/EvalSetList.test.tsx +0 -0
  821. {hawk-3.2.0 → hawk-3.3.0}/www/src/browser/JobsList.test.tsx +0 -0
  822. {hawk-3.2.0 → hawk-3.3.0}/www/src/browser/SampleList.test.tsx +0 -0
  823. {hawk-3.2.0 → hawk-3.3.0}/www/src/browser/ScanList.test.tsx +0 -0
  824. {hawk-3.2.0 → hawk-3.3.0}/www/src/components/DurationHistograms.tsx +0 -0
  825. {hawk-3.2.0 → hawk-3.3.0}/www/src/components/ErrorDisplay.tsx +0 -0
  826. {hawk-3.2.0 → hawk-3.3.0}/www/src/components/EvalSetFilter.tsx +0 -0
  827. {hawk-3.2.0 → hawk-3.3.0}/www/src/components/EvalSetList.tsx +0 -0
  828. {hawk-3.2.0 → hawk-3.3.0}/www/src/components/EvalSetStatusBar.tsx +0 -0
  829. {hawk-3.2.0 → hawk-3.3.0}/www/src/components/EvalSetTimeline.test.tsx +0 -0
  830. {hawk-3.2.0 → hawk-3.3.0}/www/src/components/EvalSetTimeline.tsx +0 -0
  831. {hawk-3.2.0 → hawk-3.3.0}/www/src/components/JobsList.test.tsx +0 -0
  832. {hawk-3.2.0 → hawk-3.3.0}/www/src/components/JobsList.tsx +0 -0
  833. {hawk-3.2.0 → hawk-3.3.0}/www/src/components/Layout.tsx +0 -0
  834. {hawk-3.2.0 → hawk-3.3.0}/www/src/components/LoadingDisplay.tsx +0 -0
  835. {hawk-3.2.0 → hawk-3.3.0}/www/src/components/RateLimitsList.test.tsx +0 -0
  836. {hawk-3.2.0 → hawk-3.3.0}/www/src/components/RateLimitsList.tsx +0 -0
  837. {hawk-3.2.0 → hawk-3.3.0}/www/src/components/SampleExplorer.tsx +0 -0
  838. {hawk-3.2.0 → hawk-3.3.0}/www/src/components/SampleList.tsx +0 -0
  839. {hawk-3.2.0 → hawk-3.3.0}/www/src/components/SamplePicker.test.tsx +0 -0
  840. {hawk-3.2.0 → hawk-3.3.0}/www/src/components/SamplePicker.tsx +0 -0
  841. {hawk-3.2.0 → hawk-3.3.0}/www/src/components/SampleSwimlanes.tsx +0 -0
  842. {hawk-3.2.0 → hawk-3.3.0}/www/src/components/SampleTimeline.test.tsx +0 -0
  843. {hawk-3.2.0 → hawk-3.3.0}/www/src/components/SampleTimeline.tsx +0 -0
  844. {hawk-3.2.0 → hawk-3.3.0}/www/src/components/ScanList.tsx +0 -0
  845. {hawk-3.2.0 → hawk-3.3.0}/www/src/components/SearchSnippet.test.tsx +0 -0
  846. {hawk-3.2.0 → hawk-3.3.0}/www/src/components/SearchSnippet.tsx +0 -0
  847. {hawk-3.2.0 → hawk-3.3.0}/www/src/components/ThemePicker.tsx +0 -0
  848. {hawk-3.2.0 → hawk-3.3.0}/www/src/components/TranscriptSearchList.tsx +0 -0
  849. {hawk-3.2.0 → hawk-3.3.0}/www/src/components/UserMenu.test.tsx +0 -0
  850. {hawk-3.2.0 → hawk-3.3.0}/www/src/components/UserMenu.tsx +0 -0
  851. {hawk-3.2.0 → hawk-3.3.0}/www/src/components/ag-grid/cellRenderers.tsx +0 -0
  852. {hawk-3.2.0 → hawk-3.3.0}/www/src/components/ag-grid/formatters.ts +0 -0
  853. {hawk-3.2.0 → hawk-3.3.0}/www/src/components/ag-grid/isCopyButtonClick.ts +0 -0
  854. {hawk-3.2.0 → hawk-3.3.0}/www/src/components/ag-grid/isLinkClick.test.ts +0 -0
  855. {hawk-3.2.0 → hawk-3.3.0}/www/src/components/ag-grid/isLinkClick.ts +0 -0
  856. {hawk-3.2.0 → hawk-3.3.0}/www/src/components/ag-grid/styles.css +0 -0
  857. {hawk-3.2.0 → hawk-3.3.0}/www/src/components/artifacts/ArtifactPanel.tsx +0 -0
  858. {hawk-3.2.0 → hawk-3.3.0}/www/src/components/artifacts/ArtifactSplitPane.tsx +0 -0
  859. {hawk-3.2.0 → hawk-3.3.0}/www/src/components/artifacts/CsvViewer.tsx +0 -0
  860. {hawk-3.2.0 → hawk-3.3.0}/www/src/components/artifacts/FileBrowser.test.tsx +0 -0
  861. {hawk-3.2.0 → hawk-3.3.0}/www/src/components/artifacts/FileBrowser.tsx +0 -0
  862. {hawk-3.2.0 → hawk-3.3.0}/www/src/components/artifacts/FileViewer.tsx +0 -0
  863. {hawk-3.2.0 → hawk-3.3.0}/www/src/components/artifacts/HtmlViewer.test.tsx +0 -0
  864. {hawk-3.2.0 → hawk-3.3.0}/www/src/components/artifacts/HtmlViewer.tsx +0 -0
  865. {hawk-3.2.0 → hawk-3.3.0}/www/src/components/artifacts/ImageViewer.tsx +0 -0
  866. {hawk-3.2.0 → hawk-3.3.0}/www/src/components/artifacts/JsonViewer.tsx +0 -0
  867. {hawk-3.2.0 → hawk-3.3.0}/www/src/components/artifacts/MarkdownViewer.tsx +0 -0
  868. {hawk-3.2.0 → hawk-3.3.0}/www/src/components/artifacts/PdfViewer.tsx +0 -0
  869. {hawk-3.2.0 → hawk-3.3.0}/www/src/components/artifacts/SvgViewer.test.tsx +0 -0
  870. {hawk-3.2.0 → hawk-3.3.0}/www/src/components/artifacts/SvgViewer.tsx +0 -0
  871. {hawk-3.2.0 → hawk-3.3.0}/www/src/components/artifacts/TextViewer.tsx +0 -0
  872. {hawk-3.2.0 → hawk-3.3.0}/www/src/components/artifacts/UnknownViewer.tsx +0 -0
  873. {hawk-3.2.0 → hawk-3.3.0}/www/src/components/artifacts/VideoViewer.tsx +0 -0
  874. {hawk-3.2.0 → hawk-3.3.0}/www/src/components/artifacts/ViewerActions.tsx +0 -0
  875. {hawk-3.2.0 → hawk-3.3.0}/www/src/components/artifacts/ViewerChrome.tsx +0 -0
  876. {hawk-3.2.0 → hawk-3.3.0}/www/src/components/artifacts/index.ts +0 -0
  877. {hawk-3.2.0 → hawk-3.3.0}/www/src/components/timeline/SummaryCards.tsx +0 -0
  878. {hawk-3.2.0 → hawk-3.3.0}/www/src/config/env.ts +0 -0
  879. {hawk-3.2.0 → hawk-3.3.0}/www/src/contexts/ArtifactViewContext.tsx +0 -0
  880. {hawk-3.2.0 → hawk-3.3.0}/www/src/contexts/AuthContext.test.tsx +0 -0
  881. {hawk-3.2.0 → hawk-3.3.0}/www/src/contexts/AuthContext.tsx +0 -0
  882. {hawk-3.2.0 → hawk-3.3.0}/www/src/hooks/useAbortController.ts +0 -0
  883. {hawk-3.2.0 → hawk-3.3.0}/www/src/hooks/useApiFetch.test.tsx +0 -0
  884. {hawk-3.2.0 → hawk-3.3.0}/www/src/hooks/useApiFetch.ts +0 -0
  885. {hawk-3.2.0 → hawk-3.3.0}/www/src/hooks/useArtifactNeighborPrefetch.test.ts +0 -0
  886. {hawk-3.2.0 → hawk-3.3.0}/www/src/hooks/useArtifactNeighborPrefetch.ts +0 -0
  887. {hawk-3.2.0 → hawk-3.3.0}/www/src/hooks/useEvalAppScrollDirection.ts +0 -0
  888. {hawk-3.2.0 → hawk-3.3.0}/www/src/hooks/useEvalSetConfig.ts +0 -0
  889. {hawk-3.2.0 → hawk-3.3.0}/www/src/hooks/useEvalSetGate.ts +0 -0
  890. {hawk-3.2.0 → hawk-3.3.0}/www/src/hooks/useEvalSetStatus.ts +0 -0
  891. {hawk-3.2.0 → hawk-3.3.0}/www/src/hooks/useEvalSetTimeline.ts +0 -0
  892. {hawk-3.2.0 → hawk-3.3.0}/www/src/hooks/useEvalSetTimelineSamples.ts +0 -0
  893. {hawk-3.2.0 → hawk-3.3.0}/www/src/hooks/useEvalSets.ts +0 -0
  894. {hawk-3.2.0 → hawk-3.3.0}/www/src/hooks/useInlinedImageHtml.ts +0 -0
  895. {hawk-3.2.0 → hawk-3.3.0}/www/src/hooks/useInspectApi.test.ts +0 -0
  896. {hawk-3.2.0 → hawk-3.3.0}/www/src/hooks/useInspectApi.ts +0 -0
  897. {hawk-3.2.0 → hawk-3.3.0}/www/src/hooks/useIsDarkTheme.ts +0 -0
  898. {hawk-3.2.0 → hawk-3.3.0}/www/src/hooks/useJobLogs.ts +0 -0
  899. {hawk-3.2.0 → hawk-3.3.0}/www/src/hooks/useJobStatus.ts +0 -0
  900. {hawk-3.2.0 → hawk-3.3.0}/www/src/hooks/useJobs.test.tsx +0 -0
  901. {hawk-3.2.0 → hawk-3.3.0}/www/src/hooks/useJobs.ts +0 -0
  902. {hawk-3.2.0 → hawk-3.3.0}/www/src/hooks/useRateLimitHistory.ts +0 -0
  903. {hawk-3.2.0 → hawk-3.3.0}/www/src/hooks/useRateLimits.ts +0 -0
  904. {hawk-3.2.0 → hawk-3.3.0}/www/src/hooks/useSampleFileUrl.ts +0 -0
  905. {hawk-3.2.0 → hawk-3.3.0}/www/src/hooks/useSampleFiles.ts +0 -0
  906. {hawk-3.2.0 → hawk-3.3.0}/www/src/hooks/useSampleMeta.ts +0 -0
  907. {hawk-3.2.0 → hawk-3.3.0}/www/src/hooks/useSampleSummary.ts +0 -0
  908. {hawk-3.2.0 → hawk-3.3.0}/www/src/hooks/useSampleTimeline.ts +0 -0
  909. {hawk-3.2.0 → hawk-3.3.0}/www/src/hooks/useSanitizedHtmlPreview.ts +0 -0
  910. {hawk-3.2.0 → hawk-3.3.0}/www/src/hooks/useScans.ts +0 -0
  911. {hawk-3.2.0 → hawk-3.3.0}/www/src/hooks/useScoutApi.ts +0 -0
  912. {hawk-3.2.0 → hawk-3.3.0}/www/src/hooks/useTextPreview.ts +0 -0
  913. {hawk-3.2.0 → hawk-3.3.0}/www/src/index.css +0 -0
  914. {hawk-3.2.0 → hawk-3.3.0}/www/src/main.tsx +0 -0
  915. {hawk-3.2.0 → hawk-3.3.0}/www/src/pages/ArtifactPage.tsx +0 -0
  916. {hawk-3.2.0 → hawk-3.3.0}/www/src/pages/EvalSetNotFoundPage.tsx +0 -0
  917. {hawk-3.2.0 → hawk-3.3.0}/www/src/pages/EvalSetPendingPage.tsx +0 -0
  918. {hawk-3.2.0 → hawk-3.3.0}/www/src/pages/EvalSetStatusPage.tsx +0 -0
  919. {hawk-3.2.0 → hawk-3.3.0}/www/src/pages/EvalSetTimelinePage.tsx +0 -0
  920. {hawk-3.2.0 → hawk-3.3.0}/www/src/pages/LaunchPage.tsx +0 -0
  921. {hawk-3.2.0 → hawk-3.3.0}/www/src/pages/OAuthCallback.test.tsx +0 -0
  922. {hawk-3.2.0 → hawk-3.3.0}/www/src/pages/OAuthCallback.tsx +0 -0
  923. {hawk-3.2.0 → hawk-3.3.0}/www/src/pages/ReportPage.tsx +0 -0
  924. {hawk-3.2.0 → hawk-3.3.0}/www/src/pages/SampleFileFullPage.tsx +0 -0
  925. {hawk-3.2.0 → hawk-3.3.0}/www/src/pages/SampleTimelinePage.tsx +0 -0
  926. {hawk-3.2.0 → hawk-3.3.0}/www/src/routes/SamplePermalink.tsx +0 -0
  927. {hawk-3.2.0 → hawk-3.3.0}/www/src/test/harness.ts +0 -0
  928. {hawk-3.2.0 → hawk-3.3.0}/www/src/theme.ts +0 -0
  929. {hawk-3.2.0 → hawk-3.3.0}/www/src/types/artifactResource.test.ts +0 -0
  930. {hawk-3.2.0 → hawk-3.3.0}/www/src/types/artifactResource.ts +0 -0
  931. {hawk-3.2.0 → hawk-3.3.0}/www/src/types/artifacts.ts +0 -0
  932. {hawk-3.2.0 → hawk-3.3.0}/www/src/types/auth.ts +0 -0
  933. {hawk-3.2.0 → hawk-3.3.0}/www/src/types/jobs.ts +0 -0
  934. {hawk-3.2.0 → hawk-3.3.0}/www/src/types/monitoring.ts +0 -0
  935. {hawk-3.2.0 → hawk-3.3.0}/www/src/types/rateLimits.ts +0 -0
  936. {hawk-3.2.0 → hawk-3.3.0}/www/src/types/samples.ts +0 -0
  937. {hawk-3.2.0 → hawk-3.3.0}/www/src/types/scans.ts +0 -0
  938. {hawk-3.2.0 → hawk-3.3.0}/www/src/types/search.ts +0 -0
  939. {hawk-3.2.0 → hawk-3.3.0}/www/src/types/timeline.ts +0 -0
  940. {hawk-3.2.0 → hawk-3.3.0}/www/src/utils/artifactRows.test.ts +0 -0
  941. {hawk-3.2.0 → hawk-3.3.0}/www/src/utils/artifactRows.ts +0 -0
  942. {hawk-3.2.0 → hawk-3.3.0}/www/src/utils/csvUtils.test.ts +0 -0
  943. {hawk-3.2.0 → hawk-3.3.0}/www/src/utils/csvUtils.ts +0 -0
  944. {hawk-3.2.0 → hawk-3.3.0}/www/src/utils/datetime.test.ts +0 -0
  945. {hawk-3.2.0 → hawk-3.3.0}/www/src/utils/datetime.ts +0 -0
  946. {hawk-3.2.0 → hawk-3.3.0}/www/src/utils/fetchText.ts +0 -0
  947. {hawk-3.2.0 → hawk-3.3.0}/www/src/utils/fileKind.test.ts +0 -0
  948. {hawk-3.2.0 → hawk-3.3.0}/www/src/utils/fileKind.ts +0 -0
  949. {hawk-3.2.0 → hawk-3.3.0}/www/src/utils/formatScores.test.ts +0 -0
  950. {hawk-3.2.0 → hawk-3.3.0}/www/src/utils/formatScores.ts +0 -0
  951. {hawk-3.2.0 → hawk-3.3.0}/www/src/utils/formatters.test.ts +0 -0
  952. {hawk-3.2.0 → hawk-3.3.0}/www/src/utils/formatters.ts +0 -0
  953. {hawk-3.2.0 → hawk-3.3.0}/www/src/utils/headerProvider.test.ts +0 -0
  954. {hawk-3.2.0 → hawk-3.3.0}/www/src/utils/headerProvider.ts +0 -0
  955. {hawk-3.2.0 → hawk-3.3.0}/www/src/utils/htmlSanitization.test.ts +0 -0
  956. {hawk-3.2.0 → hawk-3.3.0}/www/src/utils/htmlSanitization.ts +0 -0
  957. {hawk-3.2.0 → hawk-3.3.0}/www/src/utils/jobStatus.test.ts +0 -0
  958. {hawk-3.2.0 → hawk-3.3.0}/www/src/utils/jobStatus.ts +0 -0
  959. {hawk-3.2.0 → hawk-3.3.0}/www/src/utils/oauth.test.ts +0 -0
  960. {hawk-3.2.0 → hawk-3.3.0}/www/src/utils/oauth.ts +0 -0
  961. {hawk-3.2.0 → hawk-3.3.0}/www/src/utils/pkce.ts +0 -0
  962. {hawk-3.2.0 → hawk-3.3.0}/www/src/utils/refreshToken.ts +0 -0
  963. {hawk-3.2.0 → hawk-3.3.0}/www/src/utils/resolveInlineImages.test.ts +0 -0
  964. {hawk-3.2.0 → hawk-3.3.0}/www/src/utils/resolveInlineImages.ts +0 -0
  965. {hawk-3.2.0 → hawk-3.3.0}/www/src/utils/sampleContentUrls.ts +0 -0
  966. {hawk-3.2.0 → hawk-3.3.0}/www/src/utils/sampleEvalSet.test.ts +0 -0
  967. {hawk-3.2.0 → hawk-3.3.0}/www/src/utils/sampleEvalSet.ts +0 -0
  968. {hawk-3.2.0 → hawk-3.3.0}/www/src/utils/session.test.ts +0 -0
  969. {hawk-3.2.0 → hawk-3.3.0}/www/src/utils/session.ts +0 -0
  970. {hawk-3.2.0 → hawk-3.3.0}/www/src/utils/sse.test.ts +0 -0
  971. {hawk-3.2.0 → hawk-3.3.0}/www/src/utils/sse.ts +0 -0
  972. {hawk-3.2.0 → hawk-3.3.0}/www/src/utils/timeline.test.ts +0 -0
  973. {hawk-3.2.0 → hawk-3.3.0}/www/src/utils/timeline.ts +0 -0
  974. {hawk-3.2.0 → hawk-3.3.0}/www/src/utils/timelineCharts.test.ts +0 -0
  975. {hawk-3.2.0 → hawk-3.3.0}/www/src/utils/timelineCharts.ts +0 -0
  976. {hawk-3.2.0 → hawk-3.3.0}/www/src/utils/tokenValidation.test.ts +0 -0
  977. {hawk-3.2.0 → hawk-3.3.0}/www/src/utils/tokenValidation.ts +0 -0
  978. {hawk-3.2.0 → hawk-3.3.0}/www/src/utils/url.ts +0 -0
  979. {hawk-3.2.0 → hawk-3.3.0}/www/src/utils/viewerLimits.test.ts +0 -0
  980. {hawk-3.2.0 → hawk-3.3.0}/www/src/utils/viewerLimits.ts +0 -0
  981. {hawk-3.2.0 → hawk-3.3.0}/www/src/utils/yaml.test.ts +0 -0
  982. {hawk-3.2.0 → hawk-3.3.0}/www/src/utils/yaml.ts +0 -0
  983. {hawk-3.2.0 → hawk-3.3.0}/www/src/vite-env.d.ts +0 -0
  984. {hawk-3.2.0 → hawk-3.3.0}/www/tailwind.config.js +0 -0
  985. {hawk-3.2.0 → hawk-3.3.0}/www/tsconfig.json +0 -0
  986. {hawk-3.2.0 → hawk-3.3.0}/www/vite.config.ts +0 -0
  987. {hawk-3.2.0 → hawk-3.3.0}/www/vitest.browser.config.ts +0 -0
@@ -17,22 +17,6 @@ services/**
17
17
  !services/modules/*/pyproject.toml
18
18
  !services/modules/*/README.md
19
19
  !services/modules/*/uv.lock
20
- !services/modules/viewer/nginx.conf
21
-
22
- !www
23
- www/**
24
- !www/package.json
25
- !www/pnpm-lock.yaml
26
- !www/pnpm-workspace.yaml
27
- !www/index.html
28
- !www/eslint.config.js
29
- !www/tsconfig.json
30
- !www/vite.config.ts
31
- !www/tailwind.config.js
32
- !www/src
33
- !www/src/**
34
- !www/public
35
- !www/public/**
36
20
 
37
21
  hawk/tests/**
38
22
  **/.venv/**
@@ -1,5 +1,23 @@
1
1
  # Changelog
2
2
 
3
+ ## [3.3.0](https://github.com/METR/hawk/compare/v3.2.0...v3.3.0) (2026-09-08)
4
+
5
+
6
+ ### Features
7
+
8
+ * **runner:** enable adaptive model concurrency and unblock sandbox starts ([#1607](https://github.com/METR/hawk/issues/1607)) ([ed86d01](https://github.com/METR/hawk/commit/ed86d016b59dd29d13db5ea59347804de7ea45c1))
9
+
10
+
11
+ ### Bug Fixes
12
+
13
+ * **api:** export scan results by scanner key and 404 a missing parquet [SEN-189] ([#1259](https://github.com/METR/hawk/issues/1259)) ([1e15689](https://github.com/METR/hawk/commit/1e15689957cbbfca22ea31bcf5c2aeb4c3b3eafe))
14
+ * **authz:** derive a scan's ACL from the evals it read ([#1142](https://github.com/METR/hawk/issues/1142)) ([e763980](https://github.com/METR/hawk/commit/e763980a51e807fd3be43d3c20ecdc0d4c4bd4ba))
15
+ * **db:** raise statement_timeout for the a726f26fdd42 scan recompute ([#1634](https://github.com/METR/hawk/issues/1634)) ([7e9bb91](https://github.com/METR/hawk/commit/7e9bb916d9a462943c2c8380073c1b207ce643cb))
16
+ * **human-eval:** report the jumphost cause when key registration fails [SEN-240] ([#1447](https://github.com/METR/hawk/issues/1447)) ([5251885](https://github.com/METR/hawk/commit/52518856f2a915b64a96256b6f5882e008af8a91))
17
+ * **runner:** cache token-broker credentials on the pod ([#1585](https://github.com/METR/hawk/issues/1585)) ([15d1616](https://github.com/METR/hawk/commit/15d1616d8748b9217d25e2e9f9112cc2b34386a3))
18
+ * **runner:** let tasks and solvers resolve model roles at construction ([#1619](https://github.com/METR/hawk/issues/1619)) ([9b24b19](https://github.com/METR/hawk/commit/9b24b190247a664100dc1bba33786829032b995f))
19
+ * **shell:** log the failing command's output, not just its headline ([#1488](https://github.com/METR/hawk/issues/1488)) ([60a0f42](https://github.com/METR/hawk/commit/60a0f42d2f0c8f97318bbde87c3766104dc6914c))
20
+
3
21
  ## [3.2.0](https://github.com/METR/hawk/compare/v3.1.1...v3.2.0) (2026-09-07)
4
22
 
5
23
 
@@ -1,14 +1,10 @@
1
1
  # Keep this default aligned with infra.lib.config.DEFAULT_BASE_PYTHON_IMAGE.
2
2
  ARG PYTHON_BASE_IMAGE=dhi.io/python:3.13-dev
3
3
  ARG AWS_CLI_VERSION=2.27.26
4
- ARG DOCKER_VERSION=29.7.1
5
- ARG KUBECTL_VERSION=1.36.2
6
4
  ARG UV_VERSION=0.12.3
7
5
 
8
6
  FROM amazon/aws-cli:${AWS_CLI_VERSION} AS aws-cli
9
- FROM docker:${DOCKER_VERSION}-cli AS docker-cli
10
7
  FROM ghcr.io/astral-sh/uv:${UV_VERSION} AS uv
11
- FROM rancher/kubectl:v${KUBECTL_VERSION} AS kubectl
12
8
  FROM ${PYTHON_BASE_IMAGE} AS python
13
9
 
14
10
  FROM --platform=$BUILDPLATFORM alpine:3.24 AS helm
@@ -62,7 +58,13 @@ ENV UV_LINK_MODE=copy
62
58
  FROM base AS builder-base
63
59
  WORKDIR /source
64
60
  COPY pyproject.toml uv.lock ./
65
- COPY services/modules services/modules
61
+ # `uv sync --locked` only reads the path dependencies' pyproject.toml (they are
62
+ # in dev-only groups, never installed here); copying their sources would rerun
63
+ # every venv install on each lambda .py change.
64
+ COPY services/modules/eval_log_importer/pyproject.toml services/modules/eval_log_importer/
65
+ COPY services/modules/eval_log_reader/pyproject.toml services/modules/eval_log_reader/
66
+ COPY services/modules/job_status_updated/pyproject.toml services/modules/job_status_updated/
67
+ COPY services/modules/sample_editor/pyproject.toml services/modules/sample_editor/
66
68
 
67
69
  FROM builder-base AS builder-runner
68
70
  RUN --mount=type=cache,target=/root/.cache/uv \
@@ -73,8 +75,19 @@ RUN --mount=type=cache,target=/root/.cache/uv \
73
75
  --no-dev \
74
76
  --no-install-project
75
77
 
78
+ # inspect resolves restic from ~/.cache/inspect_ai/bin/restic_<version>_<platform>
79
+ # (inspect_ai/util/_restic/resolver.py), version from the installed package, so
80
+ # this stays in lockstep with the pinned inspect-ai. Build the whole destination
81
+ # tree with fixed ownership and mtimes so the runner's COPY --link layer is
82
+ # byte-stable. Linux only: the runner host and the sandboxes are linux
83
+ # (_checkpoint/_sandbox_restic/repo.py maps amd64/arm64 to linux_*).
76
84
  FROM builder-runner AS restic-cache
77
- RUN HOME=/home/nonroot inspect download restic
85
+ RUN HOME=/out/home/nonroot inspect download restic \
86
+ && rm /out/home/nonroot/.cache/inspect_ai/bin/restic_*_darwin_* \
87
+ /out/home/nonroot/.cache/inspect_ai/bin/restic_*_windows_* \
88
+ && chown -R ${USER_ID}:${GROUP_ID} /out/home/nonroot \
89
+ && chown root:root /out /out/home \
90
+ && find /out -exec touch -h -t 202001010000.00 {} +
78
91
 
79
92
  FROM builder-base AS builder-api
80
93
  RUN --mount=type=cache,target=/root/.cache/uv \
@@ -95,10 +108,10 @@ FROM base AS runner
95
108
  ENV LD_PRELOAD=libjemalloc.so.2
96
109
  ENV MALLOC_CONF=background_thread:true,dirty_decay_ms:30000,muzzy_decay_ms:30000,metadata_thp:auto
97
110
 
98
- COPY --from=docker-cli /usr/local/bin/docker /usr/local/bin/docker
99
- COPY --from=docker-cli /usr/local/libexec/docker/cli-plugins/docker-buildx /usr/local/libexec/docker/cli-plugins/docker-buildx
100
111
  COPY --from=helm /helm /usr/local/bin/helm
101
- COPY --from=kubectl /bin/kubectl /usr/local/bin/
112
+ # --link: the layer is built from the restic-cache stage alone, not this stage's
113
+ # snapshot, so its digest is identical on every build.
114
+ COPY --link --from=restic-cache /out/ /
102
115
 
103
116
  WORKDIR /home/nonroot/app
104
117
  COPY --from=builder-runner ${UV_PROJECT_ENVIRONMENT} ${UV_PROJECT_ENVIRONMENT}
@@ -115,13 +128,12 @@ RUN --mount=type=cache,target=/root/.cache/uv \
115
128
  USER nonroot
116
129
  STOPSIGNAL SIGINT
117
130
 
118
- COPY --from=restic-cache --chown=nonroot:nonroot /home/nonroot/.cache/inspect_ai /home/nonroot/.cache/inspect_ai
119
131
  ENTRYPOINT ["python", "-m", "hawk.runner.entrypoint"]
120
132
 
121
133
  FROM base AS api
122
134
  # Install graphviz. x11-common's postinst needs update-rc.d from init-system-helpers
123
135
  RUN apt-get update \
124
- && apt-get install -y init-system-helpers graphviz \
136
+ && apt-get install -y --no-install-recommends init-system-helpers graphviz \
125
137
  && rm -rf /var/lib/apt/lists/*
126
138
 
127
139
  COPY --from=aws-cli /usr/local/aws-cli/v2/current /usr/local
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: hawk
3
- Version: 3.2.0
3
+ Version: 3.3.0
4
4
  Summary: Platform for running Inspect AI evaluations and Inspect Scout scans at scale on Kubernetes
5
5
  Project-URL: Homepage, https://hawk.metr.org/
6
6
  Project-URL: Documentation, https://hawk.metr.org/
@@ -1,5 +1,43 @@
1
1
  {
2
2
  "$defs": {
3
+ "AdaptiveConnectionsBounds": {
4
+ "additionalProperties": false,
5
+ "description": "Bounds for inspect-ai's adaptive connections controller.",
6
+ "properties": {
7
+ "min": {
8
+ "description": "Lowest concurrency the controller may wind a throttled model down to.",
9
+ "exclusiveMinimum": 0,
10
+ "title": "Min",
11
+ "type": "integer"
12
+ },
13
+ "max": {
14
+ "description": "Ceiling the controller may scale up to.",
15
+ "exclusiveMinimum": 0,
16
+ "title": "Max",
17
+ "type": "integer"
18
+ },
19
+ "start": {
20
+ "anyOf": [
21
+ {
22
+ "exclusiveMinimum": 0,
23
+ "type": "integer"
24
+ },
25
+ {
26
+ "type": "null"
27
+ }
28
+ ],
29
+ "default": null,
30
+ "description": "Concurrency to start at, within [min, max]. Unset: inspect-ai's default start, clamped into the bounds.",
31
+ "title": "Start"
32
+ }
33
+ },
34
+ "required": [
35
+ "min",
36
+ "max"
37
+ ],
38
+ "title": "AdaptiveConnectionsBounds",
39
+ "type": "object"
40
+ },
3
41
  "AgentConfig": {
4
42
  "description": "Configuration for an agent.",
5
43
  "properties": {
@@ -1465,10 +1503,20 @@
1465
1503
  {
1466
1504
  "exclusiveMinimum": 0,
1467
1505
  "type": "integer"
1506
+ },
1507
+ {
1508
+ "pattern": "^\\d+-\\d+(-\\d+)?$",
1509
+ "type": "string"
1510
+ },
1511
+ {
1512
+ "$ref": "#/$defs/AdaptiveConnectionsBounds"
1513
+ },
1514
+ {
1515
+ "type": "null"
1468
1516
  }
1469
1517
  ],
1470
- "default": false,
1471
- "description": "Enable inspect-ai's adaptive connections controller, which automatically scales model API concurrency based on rate-limit feedback. Set to an integer N to also raise the controller's concurrency ceiling to N (inspect-ai shorthand for `AdaptiveConcurrency(max=N)`); `true` uses inspect-ai's default bounds. Note that an explicit per-model `max_connections` takes precedence over the adaptive controller (adaptive is silently disabled for that model), so remove `max_connections` for adaptive to apply. May become the default in a future release. See https://inspect.aisi.org.uk/models-concurrency.html#adaptive-connections.",
1518
+ "default": null,
1519
+ "description": "inspect-ai's adaptive connections controller, which scales model API concurrency up and down from rate-limit feedback instead of holding a fixed ceiling. Unset (the default) defers to inspect-ai, which enables it; `false` opts out. Set an integer N to raise the ceiling to N (inspect-ai shorthand for `AdaptiveConcurrency(max=N)`), or set the bounds directly as a mapping such as `{min: 1, max: 100}` or the shorthand `\"1-20-100\"` (`min-max` or `min-start-max`) \u2014 a `min` of 1 lets a throttled model be wound down to a single in-flight request. Note that an explicit per-model `max_connections` takes precedence (adaptive is silently disabled for that model), so remove `max_connections` for adaptive to apply. See https://inspect.aisi.org.uk/models-concurrency.html#adaptive-connections.",
1472
1520
  "title": "Adaptive Connections"
1473
1521
  },
1474
1522
  "monitor": {
@@ -361,8 +361,10 @@ async def create_human_eval(
361
361
  public_key=human.ssh_public_key,
362
362
  comment=comment,
363
363
  )
364
- except Exception:
364
+ except Exception as e:
365
365
  logger.exception("Failed to register SSH key for human eval %s", eval_set_id)
366
+ # The caller can't see server logs, so the cause travels with the error.
367
+ cause = f"{type(e).__name__}: {e}"
366
368
  rolled_back = await _uninstall_eval_set(helm_client, eval_set_id, settings)
367
369
  if rolled_back:
368
370
  # Helm release is gone, no key was ever registered — drop the
@@ -374,24 +376,24 @@ async def create_human_eval(
374
376
  raise problem.AppError(
375
377
  title="Jump host key registration failed",
376
378
  message=(
377
- "Failed to register SSH key on jump host. The Helm release "
378
- "has been uninstalled; any Datadog monitors and S3 files "
379
- "created during eval-set setup remain and will need to be "
380
- "cleaned up out of band."
379
+ f"Failed to register SSH key on jump host ({cause}). The Helm "
380
+ f"release has been uninstalled and the launch rolled back, so "
381
+ f"you can retry. Any S3 files and Datadog monitor left over "
382
+ f"from eval-set {eval_set_id}'s setup are inert."
381
383
  ),
382
384
  status_code=HTTPStatus.BAD_GATEWAY,
383
- )
385
+ ) from e
384
386
  # Rollback failed — leave the assignment row in place so a future
385
387
  # DELETE /eval_sets/{id} re-attempts cleanup of the still-running release.
386
388
  raise problem.AppError(
387
389
  title="Jump host key registration failed; rollback also failed",
388
390
  message=(
389
- f"Failed to register SSH key on jump host AND failed to tear down "
390
- f"the eval-set. Eval-set {eval_set_id} is still running and needs "
391
- f"manual cleanup via DELETE /eval_sets/{eval_set_id}."
391
+ f"Failed to register SSH key on jump host ({cause}) AND failed to "
392
+ f"tear down the eval-set. Eval-set {eval_set_id} is still running "
393
+ f"and needs manual cleanup via DELETE /eval_sets/{eval_set_id}."
392
394
  ),
393
395
  status_code=HTTPStatus.BAD_GATEWAY,
394
- )
396
+ ) from e
395
397
 
396
398
  return CreateHumanEvalResponse(
397
399
  eval_set_id=eval_set_id,
@@ -10,6 +10,7 @@ from datetime import datetime, timedelta, timezone
10
10
  from typing import TYPE_CHECKING, Annotated, Any, Final, Literal, cast
11
11
 
12
12
  import fastapi
13
+ import fastapi.concurrency
13
14
  import pydantic
14
15
  import sqlalchemy as sa
15
16
  import sqlalchemy.sql.elements as sql_elements
@@ -2153,6 +2154,31 @@ async def export_scan_results(
2153
2154
  # Fetch Arrow results (async for S3 metadata)
2154
2155
  results = await hawk.core.scan_export.get_scan_results_arrow(info.scan_location)
2155
2156
 
2157
+ # Open the parquet before the response starts: starlette sends the 200
2158
+ # before it touches the body iterator, so a missing file found inside the
2159
+ # generator can't become a 404 (SEN-189).
2160
+ try:
2161
+ reader = await fastapi.concurrency.run_in_threadpool(
2162
+ hawk.core.scan_export.open_scan_results_reader,
2163
+ results,
2164
+ info.scanner_key,
2165
+ )
2166
+ except FileNotFoundError:
2167
+ # A 404 doesn't reach Sentry; this log is the only record of the miss.
2168
+ log.warning(
2169
+ "scan_export_missing",
2170
+ extra={
2171
+ "event": "scan_export_missing",
2172
+ "scanner_result_uuid": scanner_result_uuid,
2173
+ "scan_location": info.scan_location,
2174
+ "scanner_key": info.scanner_key,
2175
+ },
2176
+ )
2177
+ raise fastapi.HTTPException(
2178
+ status_code=404,
2179
+ detail="Scan results data not found",
2180
+ ) from None
2181
+
2156
2182
  safe_scan_id = utils.sanitize_filename(info.scan_id)
2157
2183
  safe_scanner_name = utils.sanitize_filename(info.scanner_name)
2158
2184
  filename = f"{safe_scan_id}_{safe_scanner_name}.csv"
@@ -2160,7 +2186,7 @@ async def export_scan_results(
2160
2186
  # Return streaming response with sync generator
2161
2187
  # (FastAPI handles sync iterators correctly)
2162
2188
  return StreamingResponse(
2163
- hawk.core.scan_export.stream_scan_results_csv(results, info.scanner_name),
2189
+ hawk.core.scan_export.stream_scan_results_csv(reader),
2164
2190
  media_type="text/csv",
2165
2191
  headers={"Content-Disposition": f'attachment; filename="{filename}"'},
2166
2192
  )
@@ -0,0 +1,174 @@
1
+ """scan model_groups: inherit the source evals' restriction
2
+
3
+ Rewrites `compute_scan_model_groups()` so a scan's ACL is never less
4
+ restrictive than the evals whose transcripts it read, then recomputes
5
+ `scan.model_groups` for the existing rows that are safe to recompute.
6
+
7
+ Before this the function read model *names* only -- the scan's own `model`, its
8
+ `model_role` rows, and `sample_model` -- and never the source `eval`, so a
9
+ restricted model was caught only if it surfaced in `sample_model`. Live
10
+ ingestion made that a fail-open: the `__unresolved__` sentinel fires only when
11
+ some `scanner_result.sample_pk IS NULL`, which was always true for a running
12
+ eval set until live rows began resolving `sample_pk` early while `sample_model`
13
+ was still a partial lower bound. Sentinel suppressed and no restricted model yet
14
+ streamed, the scan lands on `model_groups = {}` -- read here as visible to every
15
+ authenticated user.
16
+
17
+ On prd every scan already satisfied the new invariant, making the backfill a
18
+ no-op there; it is the dev/stg live-ingest window where it can change rows.
19
+
20
+ The new *term* only ever widens, but recomputing a row does not: a scan parked
21
+ at `__unresolved__` by a deferred import can have every `sample_pk` resolved by
22
+ now, so re-deriving drops the sentinel and -- absent an inherited group -- lands
23
+ on `{}`. The backfill therefore skips rows already carrying it, as
24
+ `c7d8e9f0a1b2` does.
25
+
26
+ Revision ID: a726f26fdd42
27
+ Revises: e54f61f05480
28
+ Create Date: 2026-07-31 12:05:00.000000
29
+
30
+ """
31
+
32
+ from collections.abc import Sequence
33
+
34
+ from alembic import op
35
+
36
+ revision: str = "a726f26fdd42"
37
+ down_revision: str | None = "e54f61f05480"
38
+ branch_labels: str | Sequence[str] | None = None
39
+ depends_on: str | Sequence[str] | None = None
40
+
41
+
42
+ _COMPUTE_SCAN_MODEL_GROUPS_NEW = """
43
+ CREATE OR REPLACE FUNCTION compute_scan_model_groups(target_scan_pk uuid)
44
+ RETURNS text[]
45
+ LANGUAGE sql
46
+ STABLE
47
+ SECURITY DEFINER
48
+ SET search_path = middleman, public, pg_catalog, pg_temp
49
+ AS $$
50
+ SELECT COALESCE(array_agg(DISTINCT g.name ORDER BY g.name), ARRAY[]::text[])
51
+ FROM (
52
+ SELECT mg.name
53
+ FROM (
54
+ SELECT model AS m FROM scan WHERE pk = target_scan_pk AND model IS NOT NULL
55
+ UNION
56
+ SELECT model AS m FROM model_role WHERE scan_pk = target_scan_pk
57
+ UNION
58
+ SELECT sm.model AS m FROM sample_model sm
59
+ JOIN sample s ON s.pk = sm.sample_pk
60
+ JOIN scanner_result sr ON sr.sample_pk = s.pk
61
+ WHERE sr.scan_pk = target_scan_pk
62
+ ) models
63
+ JOIN middleman.model md ON (
64
+ md.name = models.m
65
+ OR (models.m <> ''
66
+ AND right(md.name, char_length(models.m) + 1)
67
+ = '/' || models.m)
68
+ OR (md.name <> ''
69
+ AND right(models.m, char_length(md.name) + 1)
70
+ = '/' || md.name)
71
+ )
72
+ JOIN middleman.model_group mg ON mg.pk = md.model_group_pk
73
+
74
+ UNION
75
+
76
+ SELECT source.name
77
+ FROM scanner_result sr
78
+ JOIN sample s ON s.pk = sr.sample_pk
79
+ JOIN eval e ON e.pk = s.eval_pk
80
+ CROSS JOIN LATERAL unnest(e.model_groups) AS source(name)
81
+ WHERE sr.scan_pk = target_scan_pk
82
+
83
+ UNION
84
+
85
+ SELECT '__unresolved__'::text
86
+ WHERE EXISTS (
87
+ SELECT 1 FROM scanner_result sr
88
+ WHERE sr.scan_pk = target_scan_pk
89
+ AND sr.transcript_source_type = 'eval_log'
90
+ AND sr.sample_pk IS NULL
91
+ )
92
+ ) g
93
+ $$
94
+ """
95
+
96
+
97
+ # The shape this replaces, as of c7d8e9f0a1b2: name-derived groups only, but
98
+ # already joining middleman prefix-tolerantly. Downgrading must keep that join
99
+ # or it re-opens the canonical-name fail-open (METR/hawk#1198).
100
+ _COMPUTE_SCAN_MODEL_GROUPS_OLD = """
101
+ CREATE OR REPLACE FUNCTION compute_scan_model_groups(target_scan_pk uuid)
102
+ RETURNS text[]
103
+ LANGUAGE sql
104
+ STABLE
105
+ SECURITY DEFINER
106
+ SET search_path = middleman, public, pg_catalog, pg_temp
107
+ AS $$
108
+ SELECT COALESCE(array_agg(DISTINCT mg.name ORDER BY mg.name), ARRAY[]::text[])
109
+ || CASE WHEN EXISTS (
110
+ SELECT 1 FROM scanner_result sr
111
+ WHERE sr.scan_pk = target_scan_pk
112
+ AND sr.transcript_source_type = 'eval_log'
113
+ AND sr.sample_pk IS NULL
114
+ ) THEN ARRAY['__unresolved__']
115
+ ELSE ARRAY[]::text[]
116
+ END
117
+ FROM (
118
+ SELECT model AS m FROM scan WHERE pk = target_scan_pk AND model IS NOT NULL
119
+ UNION
120
+ SELECT model AS m FROM model_role WHERE scan_pk = target_scan_pk
121
+ UNION
122
+ SELECT sm.model AS m FROM sample_model sm
123
+ JOIN sample s ON s.pk = sm.sample_pk
124
+ JOIN scanner_result sr ON sr.sample_pk = s.pk
125
+ WHERE sr.scan_pk = target_scan_pk
126
+ ) models
127
+ JOIN middleman.model md ON (
128
+ md.name = models.m
129
+ OR (models.m <> ''
130
+ AND right(md.name, char_length(models.m) + 1)
131
+ = '/' || models.m)
132
+ OR (md.name <> ''
133
+ AND right(models.m, char_length(md.name) + 1)
134
+ = '/' || md.name)
135
+ )
136
+ JOIN middleman.model_group mg ON mg.pk = md.model_group_pk
137
+ $$
138
+ """
139
+
140
+
141
+ # This bulk pass never recomputes a row parked at the ``__unresolved__`` sentinel
142
+ # (a deferred/failed import that must stay hidden): re-deriving could return an
143
+ # empty array and flip it from hidden to world-visible, and a backfill has no way
144
+ # to tell such a row from one it should fix. Same guard as `c7d8e9f0a1b2`. The
145
+ # runtime path is unguarded on purpose -- see `hawk.core.db.scan_writes`.
146
+ _RECOMPUTE_SCAN = """
147
+ UPDATE scan AS s
148
+ SET model_groups = compute_scan_model_groups(s.pk)
149
+ WHERE s.model_groups IS DISTINCT FROM compute_scan_model_groups(s.pk)
150
+ AND (s.model_groups IS NULL OR NOT (s.model_groups @> ARRAY['__unresolved__']))
151
+ """
152
+
153
+
154
+ def upgrade() -> None:
155
+ op.execute(_COMPUTE_SCAN_MODEL_GROUPS_NEW)
156
+ # The recompute calls compute_scan_model_groups() for every in-scope scan
157
+ # (WHERE), and again for each row it changes (SET). Each call walks that
158
+ # scan's scanner_result -> sample -> eval rows; on prd (5.1k scans, 8.2M
159
+ # scanner_result rows) one full pass measured ~17 min on the reader, so the
160
+ # 5-min default statement_timeout (connection.get_url_and_engine_args)
161
+ # cancelled it and failed the deploy. Like `3af9c05e1d76`, raise it for
162
+ # this transaction only. Keep it below the db_migrate.py 60-min poll cap:
163
+ # past that the harness stops the task and nothing commits either way.
164
+ op.execute("SET LOCAL statement_timeout = '50min'")
165
+ op.execute(_RECOMPUTE_SCAN)
166
+
167
+
168
+ def downgrade() -> None:
169
+ # Asymmetric on purpose, following `c7d8e9f0a1b2`: reinstate the old body but
170
+ # do NOT recompute. Under the old body a recompute strips the inherited eval
171
+ # groups, re-publishing precisely the rows this migration restricted -- which
172
+ # the `upgrade head && downgrade -1 && upgrade head` loop would do routinely.
173
+ # Leaving the cache stricter stays reversible: re-upgrading rebuilds it.
174
+ op.execute(_COMPUTE_SCAN_MODEL_GROUPS_OLD)
@@ -520,31 +520,60 @@ refresh_eval_model_groups_ddls: Final = [
520
520
 
521
521
  # --- Denormalized model_groups for scan ---
522
522
 
523
- # Mirrors compute_eval_model_groups, from scan.model, model_role (scan_pk), and
524
- # sample_model via scanner_result. Appends `__unresolved__` when a scanner_result
525
- # is missing its sample_pk (groups are then an incomplete lower bound).
523
+ # The scan's own models, unioned with the groups of the evals it read. Empty =
524
+ # fail-open (visible to all), so a missed group is a leak.
526
525
  COMPUTE_SCAN_MODEL_GROUPS_BODY: Final = f"""\
527
- SELECT COALESCE(array_agg(DISTINCT mg.name ORDER BY mg.name), ARRAY[]::text[])
528
- || CASE WHEN EXISTS (
526
+ SELECT COALESCE(array_agg(DISTINCT g.name ORDER BY g.name), ARRAY[]::text[])
527
+ FROM (
528
+ -- (a) The scan's own models. The middleman join is prefix-tolerant (see
529
+ -- model_name_match_sql), as in compute_eval_model_groups.
530
+ SELECT mg.name
531
+ FROM (
532
+ SELECT model AS m FROM scan WHERE pk = target_scan_pk AND model IS NOT NULL
533
+ UNION
534
+ SELECT model AS m FROM model_role WHERE scan_pk = target_scan_pk
535
+ UNION
536
+ SELECT sm.model AS m FROM sample_model sm
537
+ JOIN sample s ON s.pk = sm.sample_pk
538
+ JOIN scanner_result sr ON sr.sample_pk = s.pk
539
+ WHERE sr.scan_pk = target_scan_pk
540
+ ) models
541
+ JOIN middleman.model md ON {model_name_match_sql("md.name", "models.m")}
542
+ JOIN middleman.model_group mg ON mg.pk = md.model_group_pk
543
+
544
+ UNION
545
+
546
+ -- (b) The source-side restriction: a scan is no less restricted than the
547
+ -- transcripts it read. Reusing `eval.model_groups` rather than re-deriving
548
+ -- it keeps the two sides from drifting, and inherits whatever the eval side
549
+ -- later learns.
550
+ --
551
+ -- NOT fail-closed in general: `eval.model_groups` is itself empty for an
552
+ -- eval whose models resolve to no group, and empty reads as unrestricted.
553
+ -- What this closes is a restricted model registered while `sample_model`
554
+ -- lags; making the eval side fail-closed is METR/hawk#1450.
555
+ --
556
+ -- `unnest` of a NULL `model_groups` yields no rows, so an unrestricted
557
+ -- eval contributes nothing rather than dropping the whole row.
558
+ SELECT source.name
559
+ FROM scanner_result sr
560
+ JOIN sample s ON s.pk = sr.sample_pk
561
+ JOIN eval e ON e.pk = s.eval_pk
562
+ CROSS JOIN LATERAL unnest(e.model_groups) AS source(name)
563
+ WHERE sr.scan_pk = target_scan_pk
564
+
565
+ UNION
566
+
567
+ -- (c) A transcript with no warehouse row at all: (b) cannot see an eval
568
+ -- that was never resolved to a sample.
569
+ SELECT '__unresolved__'::text
570
+ WHERE EXISTS (
529
571
  SELECT 1 FROM scanner_result sr
530
572
  WHERE sr.scan_pk = target_scan_pk
531
573
  AND sr.transcript_source_type = 'eval_log'
532
574
  AND sr.sample_pk IS NULL
533
- ) THEN ARRAY['__unresolved__']
534
- ELSE ARRAY[]::text[]
535
- END
536
- FROM (
537
- SELECT model AS m FROM scan WHERE pk = target_scan_pk AND model IS NOT NULL
538
- UNION
539
- SELECT model AS m FROM model_role WHERE scan_pk = target_scan_pk
540
- UNION
541
- SELECT sm.model AS m FROM sample_model sm
542
- JOIN sample s ON s.pk = sm.sample_pk
543
- JOIN scanner_result sr ON sr.sample_pk = s.pk
544
- WHERE sr.scan_pk = target_scan_pk
545
- ) models
546
- JOIN middleman.model md ON {model_name_match_sql("md.name", "models.m")}
547
- JOIN middleman.model_group mg ON mg.pk = md.model_group_pk\
575
+ )
576
+ ) g\
548
577
  """
549
578
 
550
579
 
@@ -0,0 +1,58 @@
1
+ """Writes to `scan` rows that are owned by something other than the scan itself."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import typing
6
+
7
+ import sqlalchemy
8
+ from sqlalchemy import sql
9
+ from sqlalchemy.dialects import postgresql
10
+ from sqlmodel import col
11
+
12
+ from hawk.core.db import models
13
+
14
+ if typing.TYPE_CHECKING:
15
+ import uuid
16
+
17
+ import sqlalchemy.ext.asyncio as async_sa
18
+
19
+
20
+ async def recompute_dependent_scan_model_groups(
21
+ session: async_sa.AsyncSession, eval_pk: uuid.UUID
22
+ ) -> None:
23
+ """Re-stamp the ACL of every scan that read `eval_pk`'s samples."""
24
+ # The `scan.model_groups` triggers fire on `scan`, `model_role` and
25
+ # `scanner_result` -- never on the eval-side inputs the ACL is derived from,
26
+ # so without this call a scan computed while its source eval was still
27
+ # importing keeps that answer forever.
28
+ #
29
+ # Deliberately not a `sample_model` row trigger: that is the O(n^2)
30
+ # full-scan aggregate the `hawk.defer_scan_model_groups` GUC exists to
31
+ # avoid. This runs once per settling eval, bounded by the number of scans
32
+ # over it, which is normally zero.
33
+ #
34
+ # Unguarded on `__unresolved__`, unlike the a726f26fdd42 backfill: that
35
+ # guard is a backfill-only rule, because a bulk pass cannot tell a row it
36
+ # should leave alone from one it should fix. Here the eval that parked the
37
+ # sentinel is the eval now settling, so recomputing it is the point --
38
+ # `refresh_scan_model_groups` and the scan writer's own finalize are
39
+ # likewise unguarded.
40
+ dependent_scans = (
41
+ sqlalchemy.select(col(models.ScannerResult.scan_pk))
42
+ .join(
43
+ models.Sample,
44
+ col(models.Sample.pk) == col(models.ScannerResult.sample_pk),
45
+ )
46
+ .where(col(models.Sample.eval_pk) == eval_pk)
47
+ .distinct()
48
+ )
49
+ await session.execute(
50
+ sqlalchemy.update(models.Scan)
51
+ .where(col(models.Scan.pk).in_(dependent_scans))
52
+ .values(
53
+ model_groups=sql.func.compute_scan_model_groups(
54
+ col(models.Scan.pk),
55
+ type_=postgresql.ARRAY(sqlalchemy.Text),
56
+ )
57
+ )
58
+ )
@@ -17,7 +17,7 @@ from sqlalchemy.dialects import postgresql
17
17
  from sqlmodel import col
18
18
 
19
19
  import hawk.core.exceptions as hawk_exceptions
20
- from hawk.core.db import models, serialization, upsert
20
+ from hawk.core.db import models, scan_writes, serialization, upsert
21
21
  from hawk.core.exceptions import exception_context
22
22
  from hawk.core.importer.eval import externalization, records, writer
23
23
 
@@ -262,6 +262,15 @@ class PostgresWriter(writer.EvalLogWriter):
262
262
  await _commit_import_status(
263
263
  session=self.session, eval_db_pk=self.eval_pk, status="success"
264
264
  )
265
+ # Deliberately after the stamp commits, not inside its transaction: the
266
+ # recompute can wait on scan row locks, and a block or timeout there
267
+ # must not cost the stamp (an unstamped eval is re-imported in full).
268
+ # The cost of the split is a window where the scan ACL trails the eval
269
+ # groups it is derived from; it closes on the next settle of this eval.
270
+ await scan_writes.recompute_dependent_scan_model_groups(
271
+ self.session, self.eval_pk
272
+ )
273
+ await self.session.commit()
265
274
 
266
275
  logger.info(
267
276
  "Eval import committed",
@@ -289,6 +298,13 @@ class PostgresWriter(writer.EvalLogWriter):
289
298
  await _commit_import_status(
290
299
  session=self.session, eval_db_pk=self.eval_pk, status="failed"
291
300
  )
301
+ # A failed import still settles the eval's groups, and nothing else
302
+ # would repair a scan left stale against them. After the stamp, for
303
+ # the same reason as in finalize().
304
+ await scan_writes.recompute_dependent_scan_model_groups(
305
+ self.session, self.eval_pk
306
+ )
307
+ await self.session.commit()
292
308
  except Exception as e: # noqa: BLE001
293
309
  logger.error(
294
310
  "Failed to mark eval import as failed; original error preserved",