surf-agentic-base 0.3.2__tar.gz → 0.3.3__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 (167) hide show
  1. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/CITATION.cff +1 -1
  2. {surf_agentic_base-0.3.2/src/surf_agentic_base.egg-info → surf_agentic_base-0.3.3}/PKG-INFO +1 -1
  3. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/docs/schemas/OutcomeRunFacet.json +3 -2
  4. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/src/agentic_base/domain/outcomes.py +11 -2
  5. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/src/agentic_base/provenance/__init__.py +2 -0
  6. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/src/agentic_base/provenance/emit.py +19 -1
  7. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3/src/surf_agentic_base.egg-info}/PKG-INFO +1 -1
  8. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/src/surf_agentic_base.egg-info/scm_version.json +2 -2
  9. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/tests/domain/test_outcomes.py +16 -0
  10. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/tests/provenance/test_emit.py +28 -0
  11. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/.dockerignore +0 -0
  12. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/.github/CODEOWNERS +0 -0
  13. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
  14. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  15. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
  16. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  17. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/.github/allowed_signers +0 -0
  18. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/.github/dependabot.yml +0 -0
  19. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/.github/release.yml +0 -0
  20. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/.github/renovate.json5 +0 -0
  21. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/.github/workflows/ci.yml +0 -0
  22. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/.github/workflows/label.yml +0 -0
  23. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/.github/workflows/release.yml +0 -0
  24. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/.gitignore +0 -0
  25. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/.markdownlint-cli2.jsonc +0 -0
  26. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/.pre-commit-config.yaml +0 -0
  27. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/CODE_OF_CONDUCT.md +0 -0
  28. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/CONTRIBUTING.md +0 -0
  29. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/Dockerfile +0 -0
  30. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/Justfile +0 -0
  31. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/LICENSE +0 -0
  32. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/README.md +0 -0
  33. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/SECURITY.md +0 -0
  34. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/START_HERE.md +0 -0
  35. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/charts/app/.helmignore +0 -0
  36. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/charts/app/Chart.yaml +0 -0
  37. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/charts/app/templates/NOTES.txt +0 -0
  38. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/charts/app/templates/_helpers.tpl +0 -0
  39. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/charts/app/templates/deployment.yaml +0 -0
  40. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/charts/app/templates/hpa.yaml +0 -0
  41. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/charts/app/templates/ingress.yaml +0 -0
  42. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/charts/app/templates/networkpolicy.yaml +0 -0
  43. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/charts/app/templates/poddisruptionbudget.yaml +0 -0
  44. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/charts/app/templates/prometheusrule.yaml +0 -0
  45. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/charts/app/templates/service.yaml +0 -0
  46. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/charts/app/templates/serviceaccount.yaml +0 -0
  47. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/charts/app/templates/servicemonitor.yaml +0 -0
  48. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/charts/app/templates/tests/test-connection.yaml +0 -0
  49. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/charts/app/values.yaml +0 -0
  50. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/docs/ENGINEERING.md +0 -0
  51. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/docs/OBSERVABILITY.md +0 -0
  52. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/docs/architecture/boundaries.md +0 -0
  53. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/docs/architecture/compliance.md +0 -0
  54. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/docs/architecture/deployment-overlay.md +0 -0
  55. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/docs/architecture/from-agentic-env.md +0 -0
  56. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/docs/architecture/go-live-on-sdp.md +0 -0
  57. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/docs/architecture/kubernetes.md +0 -0
  58. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/docs/architecture/layering.md +0 -0
  59. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/docs/architecture/move-plan.md +0 -0
  60. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/docs/architecture/operational-traps.md +0 -0
  61. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/docs/architecture/picture.md +0 -0
  62. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/docs/architecture/picture.svg +0 -0
  63. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/docs/architecture/process.md +0 -0
  64. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/docs/architecture/proposals.md +0 -0
  65. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/docs/architecture/reuse-ledger.md +0 -0
  66. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/docs/decisions.md +0 -0
  67. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/docs/include-readme.md +0 -0
  68. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/docs/index.md +0 -0
  69. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/mkdocs.yml +0 -0
  70. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/overlay.cfg +0 -0
  71. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/pyproject.toml +0 -0
  72. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/scripts/__init__.py +0 -0
  73. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/scripts/assert_no_permitted_failures.py +0 -0
  74. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/scripts/check_wheel_imports.py +0 -0
  75. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/scripts/overlay.py +0 -0
  76. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/setup.cfg +0 -0
  77. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/src/agentic_base/__init__.py +0 -0
  78. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/src/agentic_base/client.py +0 -0
  79. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/src/agentic_base/code_policy/__init__.py +0 -0
  80. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/src/agentic_base/code_policy/policy.py +0 -0
  81. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/src/agentic_base/config.py +0 -0
  82. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/src/agentic_base/db.py +0 -0
  83. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/src/agentic_base/domain/__init__.py +0 -0
  84. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/src/agentic_base/domain/epochs.py +0 -0
  85. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/src/agentic_base/domain/integrity.py +0 -0
  86. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/src/agentic_base/domain/run_record.py +0 -0
  87. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/src/agentic_base/domain/validity.py +0 -0
  88. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/src/agentic_base/hpc/__init__.py +0 -0
  89. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/src/agentic_base/hpc/clusters.py +0 -0
  90. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/src/agentic_base/hpc/job_result.py +0 -0
  91. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/src/agentic_base/hpc/profiles/lumi.yaml +0 -0
  92. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/src/agentic_base/hpc/profiles/snellius.yaml +0 -0
  93. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/src/agentic_base/limits.py +0 -0
  94. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/src/agentic_base/llm/__init__.py +0 -0
  95. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/src/agentic_base/llm/health.py +0 -0
  96. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/src/agentic_base/llm/resilience.py +0 -0
  97. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/src/agentic_base/main.py +0 -0
  98. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/src/agentic_base/mcp/__init__.py +0 -0
  99. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/src/agentic_base/mcp/server.py +0 -0
  100. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/src/agentic_base/observability/__init__.py +0 -0
  101. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/src/agentic_base/observability/conventions.py +0 -0
  102. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/src/agentic_base/observability/tracing.py +0 -0
  103. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/src/agentic_base/provenance/mlflow_export.py +0 -0
  104. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/src/agentic_base/py.typed +0 -0
  105. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/src/agentic_base/recording.py +0 -0
  106. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/src/agentic_base/routers/__init__.py +0 -0
  107. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/src/agentic_base/routers/health.py +0 -0
  108. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/src/agentic_base/routers/runs.py +0 -0
  109. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/src/agentic_base/security/__init__.py +0 -0
  110. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/src/agentic_base/security/netsec.py +0 -0
  111. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/src/agentic_base/tools/__init__.py +0 -0
  112. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/src/agentic_base/tools/types.py +0 -0
  113. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/src/agentic_base/utils/__init__.py +0 -0
  114. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/src/agentic_base/utils/logging.py +0 -0
  115. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/src/surf_agentic_base.egg-info/SOURCES.txt +0 -0
  116. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/src/surf_agentic_base.egg-info/dependency_links.txt +0 -0
  117. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/src/surf_agentic_base.egg-info/requires.txt +0 -0
  118. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/src/surf_agentic_base.egg-info/scm_file_list.json +0 -0
  119. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/src/surf_agentic_base.egg-info/top_level.txt +0 -0
  120. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/tests/__init__.py +0 -0
  121. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/tests/client/__init__.py +0 -0
  122. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/tests/client/test_client.py +0 -0
  123. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/tests/code_policy/__init__.py +0 -0
  124. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/tests/code_policy/test_policy.py +0 -0
  125. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/tests/conftest.py +0 -0
  126. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/tests/domain/__init__.py +0 -0
  127. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/tests/domain/test_epochs.py +0 -0
  128. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/tests/domain/test_integrity.py +0 -0
  129. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/tests/domain/test_run_record.py +0 -0
  130. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/tests/domain/test_validity.py +0 -0
  131. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/tests/hpc/__init__.py +0 -0
  132. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/tests/hpc/test_clusters.py +0 -0
  133. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/tests/hpc/test_job_result.py +0 -0
  134. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/tests/lessons/__init__.py +0 -0
  135. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/tests/lessons/test_a_null_from_a_mechanism_that_never_fired.py +0 -0
  136. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/tests/llm/__init__.py +0 -0
  137. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/tests/llm/test_health.py +0 -0
  138. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/tests/llm/test_resilience.py +0 -0
  139. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/tests/mcp/__init__.py +0 -0
  140. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/tests/mcp/test_server.py +0 -0
  141. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/tests/observability/__init__.py +0 -0
  142. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/tests/observability/test_conventions.py +0 -0
  143. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/tests/observability/test_recipes.py +0 -0
  144. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/tests/observability/test_tracing.py +0 -0
  145. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/tests/provenance/__init__.py +0 -0
  146. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/tests/provenance/test_mlflow_export.py +0 -0
  147. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/tests/recording/__init__.py +0 -0
  148. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/tests/recording/test_recording.py +0 -0
  149. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/tests/routers/__init__.py +0 -0
  150. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/tests/routers/test_health.py +0 -0
  151. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/tests/routers/test_runs.py +0 -0
  152. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/tests/security/__init__.py +0 -0
  153. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/tests/security/test_netsec.py +0 -0
  154. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/tests/test_chart.py +0 -0
  155. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/tests/test_check_wheel_imports.py +0 -0
  156. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/tests/test_config.py +0 -0
  157. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/tests/test_limits.py +0 -0
  158. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/tests/test_overlay_contract.py +0 -0
  159. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/tests/test_permitted_failures.py +0 -0
  160. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/tests/test_portable_surface.py +0 -0
  161. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/tests/test_process.py +0 -0
  162. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/tests/test_reuse_ledger.py +0 -0
  163. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/tests/tools/__init__.py +0 -0
  164. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/tests/tools/test_types.py +0 -0
  165. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/tests/utils/__init__.py +0 -0
  166. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/tests/utils/test_logging.py +0 -0
  167. {surf_agentic_base-0.3.2 → surf_agentic_base-0.3.3}/uv.lock +0 -0
@@ -11,7 +11,7 @@ authors:
11
11
  - family-names: Podareanu
12
12
  given-names: Damian
13
13
  affiliation: SURF
14
- version: 0.3.2
14
+ version: 0.3.3
15
15
  date-released: "2026-09-12"
16
16
  license: EUPL-1.2
17
17
  repository-code: "https://github.com/saradamian/agentic-base"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: surf-agentic-base
3
- Version: 0.3.2
3
+ Version: 0.3.3
4
4
  Summary: Agentic base layer: run provenance, comparison validity, and shared safety primitives.
5
5
  Author: SURF
6
6
  License-Expression: EUPL-1.2
@@ -7,7 +7,7 @@
7
7
  "allOf": [{ "$ref": "https://openlineage.io/spec/2-0-2/OpenLineage.json#/$defs/RunFacet" }],
8
8
  "properties": {
9
9
  "resolved": { "type": ["boolean", "null"], "description": "The outcome, or null when no label has been attached." },
10
- "labelSource": { "type": "string", "enum": ["unlabelled", "self_reported", "convenience_verifier", "official_harness", "human"], "description": "Who decided the outcome." },
10
+ "labelSource": { "type": "string", "enum": ["unlabelled", "self_reported", "convenience_verifier", "official_harness", "benchmark_grader", "human"], "description": "Who decided the outcome." },
11
11
  "authority": { "type": "string", "enum": ["none", "diagnostic", "authoritative"], "description": "Whether the label may be cited, independent of its modality." },
12
12
  "degraded": { "type": "boolean", "description": "True when the scoring instrument was not working and returned its fail-open default." },
13
13
  "instrument": { "type": "string" },
@@ -18,7 +18,8 @@
18
18
  "promptTokens": { "type": "integer" },
19
19
  "completionTokens": { "type": "integer" },
20
20
  "elapsedMs": { "type": "number" },
21
- "joules": { "type": "number", "description": "Physical energy, kept apart from tokens and elapsed time because each prices a different thing." }
21
+ "joules": { "type": "number", "description": "Physical energy, kept apart from tokens and elapsed time because each prices a different thing." },
22
+ "sourceRunId": { "type": "string", "description": "The producer's own run id. The event's runId is this when it is a UUID and a uuid5 derived from it otherwise." }
22
23
  },
23
24
  "required": ["labelSource", "authority", "degraded"]
24
25
  }
@@ -52,12 +52,19 @@ class LabelSource(str, enum.Enum):
52
52
  contrast."""
53
53
 
54
54
  OFFICIAL_HARNESS = "official_harness"
55
- """The benchmark's own authoritative scorer."""
55
+ """The benchmark's own authoritative scorer, published as such: the SWE-bench harness."""
56
+
57
+ BENCHMARK_GRADER = "benchmark_grader"
58
+ """A benchmark's own grader where the benchmark ships no separate harness: a tau environment
59
+ reward, a Terminal-Bench grader, an ARE validator. Authoritative for that benchmark, and
60
+ named apart from the harness because a reader must not assume the SWE-bench calibration."""
56
61
 
57
62
  HUMAN = "human"
58
63
 
59
64
 
60
- CITABLE_LABEL_SOURCES = frozenset({LabelSource.OFFICIAL_HARNESS, LabelSource.HUMAN})
65
+ CITABLE_LABEL_SOURCES = frozenset(
66
+ {LabelSource.OFFICIAL_HARNESS, LabelSource.BENCHMARK_GRADER, LabelSource.HUMAN}
67
+ )
61
68
  """Sources whose labels may be reported as results. Everything else is a diagnostic."""
62
69
 
63
70
 
@@ -81,6 +88,7 @@ _AUTHORITY: dict[LabelSource, LabelAuthority] = {
81
88
  LabelSource.SELF_REPORTED: LabelAuthority.DIAGNOSTIC,
82
89
  LabelSource.CONVENIENCE_VERIFIER: LabelAuthority.DIAGNOSTIC,
83
90
  LabelSource.OFFICIAL_HARNESS: LabelAuthority.AUTHORITATIVE,
91
+ LabelSource.BENCHMARK_GRADER: LabelAuthority.AUTHORITATIVE,
84
92
  LabelSource.HUMAN: LabelAuthority.AUTHORITATIVE,
85
93
  }
86
94
 
@@ -89,6 +97,7 @@ _MLFLOW_SOURCE_TYPE: dict[LabelSource, str] = {
89
97
  LabelSource.SELF_REPORTED: "LLM_JUDGE",
90
98
  LabelSource.CONVENIENCE_VERIFIER: "CODE",
91
99
  LabelSource.OFFICIAL_HARNESS: "CODE",
100
+ LabelSource.BENCHMARK_GRADER: "CODE",
92
101
  LabelSource.HUMAN: "HUMAN",
93
102
  }
94
103
 
@@ -11,6 +11,7 @@ schema file per format under ``docs/schemas``.
11
11
  from agentic_base.provenance.emit import (
12
12
  OUTCOME_FACET_SCHEMA,
13
13
  PROCESS_RUN_CRATE_PROFILE,
14
+ openlineage_run_id,
14
15
  to_openlineage,
15
16
  to_process_run_crate,
16
17
  to_prov,
@@ -19,6 +20,7 @@ from agentic_base.provenance.emit import (
19
20
  __all__ = [
20
21
  "OUTCOME_FACET_SCHEMA",
21
22
  "PROCESS_RUN_CRATE_PROFILE",
23
+ "openlineage_run_id",
22
24
  "to_openlineage",
23
25
  "to_process_run_crate",
24
26
  "to_prov",
@@ -4,6 +4,7 @@ without the ``provenance`` extra and a caller without it gets one sentence namin
4
4
  from __future__ import annotations
5
5
 
6
6
  import json
7
+ import uuid
7
8
  from datetime import datetime, timezone
8
9
  from pathlib import Path
9
10
  from typing import TYPE_CHECKING, Any
@@ -19,6 +20,21 @@ PRODUCER = "https://github.com/saradamian/agentic-base"
19
20
  OUTCOME_FACET_SCHEMA = "https://github.com/saradamian/agentic-base/blob/main/docs/schemas/OutcomeRunFacet.json"
20
21
  PROCESS_RUN_CRATE_PROFILE = "https://w3id.org/ro/wfrun/process/0.5"
21
22
  EXTRA = "provenance"
23
+ RUN_ID_NAMESPACE = uuid.uuid5(uuid.NAMESPACE_URL, PRODUCER)
24
+ """Namespace for deriving an OpenLineage run UUID from a run id that is not one."""
25
+
26
+
27
+ def openlineage_run_id(run_id: str) -> str:
28
+ """The UUID OpenLineage requires for a run, derived when *run_id* is not one.
29
+
30
+ PROV and RO-Crate take any string; OpenLineage's ``Run.runId`` must be a UUID and the
31
+ library fails on anything else. A consumer keying runs by an integer or a slug gets one
32
+ stable rule here rather than three private ones, and the original id travels in the facet.
33
+ """
34
+ try:
35
+ return str(uuid.UUID(run_id))
36
+ except ValueError:
37
+ return str(uuid.uuid5(RUN_ID_NAMESPACE, run_id))
22
38
 
23
39
 
24
40
  def _need(module: str) -> None:
@@ -143,6 +159,7 @@ def to_openlineage(run: RunRecordCreate, run_id: str, created_at: datetime) -> R
143
159
  completionTokens: int = 0
144
160
  elapsedMs: float = 0.0
145
161
  joules: float = 0.0
162
+ sourceRunId: str = ""
146
163
 
147
164
  @staticmethod
148
165
  def _get_schema() -> str:
@@ -164,6 +181,7 @@ def to_openlineage(run: RunRecordCreate, run_id: str, created_at: datetime) -> R
164
181
  completionTokens=run.completion_tokens,
165
182
  elapsedMs=run.elapsed_ms,
166
183
  joules=run.joules,
184
+ sourceRunId=run_id,
167
185
  ),
168
186
  }
169
187
  versions = run.component_versions
@@ -182,7 +200,7 @@ def to_openlineage(run: RunRecordCreate, run_id: str, created_at: datetime) -> R
182
200
  eventTime=_iso(created_at),
183
201
  producer=PRODUCER,
184
202
  eventType=state,
185
- run=Run(runId=run_id, facets=facets),
203
+ run=Run(runId=openlineage_run_id(run_id), facets=facets),
186
204
  job=Job(namespace=run.tenant, name=run.arm or "(unset)"),
187
205
  inputs=inputs,
188
206
  outputs=[],
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: surf-agentic-base
3
- Version: 0.3.2
3
+ Version: 0.3.3
4
4
  Summary: Agentic base layer: run provenance, comparison validity, and shared safety primitives.
5
5
  Author: SURF
6
6
  License-Expression: EUPL-1.2
@@ -1,7 +1,7 @@
1
1
  {
2
- "tag": "0.3.2",
2
+ "tag": "0.3.3",
3
3
  "distance": 0,
4
- "node": "g374920070a759fc6f8a4924a83529c6f0e66226c",
4
+ "node": "g975166d0784fe4be5f7e10196ecf812b58a1edae",
5
5
  "dirty": false,
6
6
  "branch": "HEAD",
7
7
  "node_date": "2026-09-12"
@@ -141,3 +141,19 @@ def test_tenant_and_code_revision_have_no_defaults() -> None:
141
141
  RunRecordCreate(code_revision="abc123")
142
142
  with pytest.raises(ValueError):
143
143
  RunRecordCreate(tenant="hpml")
144
+
145
+
146
+ def test_a_benchmarks_own_grader_is_authoritative_and_citable() -> None:
147
+ """tau, Terminal-Bench and ARE ship a grader and no separate harness; their verdict is the
148
+ benchmark's own, and a consumer must not have to file it as a convenience check."""
149
+ from agentic_base.domain.outcomes import (
150
+ CITABLE_LABEL_SOURCES,
151
+ LabelAuthority,
152
+ LabelSource,
153
+ authority_of,
154
+ mlflow_source_type,
155
+ )
156
+
157
+ assert LabelSource.BENCHMARK_GRADER in CITABLE_LABEL_SOURCES
158
+ assert authority_of(LabelSource.BENCHMARK_GRADER) is LabelAuthority.AUTHORITATIVE
159
+ assert mlflow_source_type(LabelSource.BENCHMARK_GRADER) == "CODE"
@@ -204,3 +204,31 @@ def test_the_module_imports_without_the_extra_and_names_it_when_called(
204
204
 
205
205
  with pytest.raises(ImportError, match=r"surf-agentic-base\[provenance\]"):
206
206
  module.to_prov(_run(), "abc", CREATED)
207
+
208
+
209
+ def test_a_run_id_that_is_not_a_uuid_becomes_a_stable_uuid_and_travels_in_the_facet() -> (
210
+ None
211
+ ):
212
+ from openlineage.client.serde import Serde
213
+
214
+ from agentic_base.provenance import openlineage_run_id
215
+
216
+ first = json.loads(Serde.to_json(to_openlineage(_run(), "journal-42", CREATED)))
217
+ second = json.loads(Serde.to_json(to_openlineage(_run(), "journal-42", CREATED)))
218
+
219
+ assert (
220
+ first["run"]["runId"]
221
+ == second["run"]["runId"]
222
+ == openlineage_run_id("journal-42")
223
+ )
224
+ assert first["run"]["runId"] != "journal-42"
225
+ assert first["run"]["facets"]["agenticBaseOutcome"]["sourceRunId"] == "journal-42"
226
+
227
+
228
+ def test_a_run_id_that_is_a_uuid_is_kept_as_is() -> None:
229
+ from agentic_base.provenance import openlineage_run_id
230
+
231
+ assert (
232
+ openlineage_run_id("C5A4B1E0-0000-4000-8000-000000000001")
233
+ == "c5a4b1e0-0000-4000-8000-000000000001"
234
+ )