synth-optimizers 0.2.7.dev20260814__tar.gz → 0.2.8.dev20260814__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 (111) hide show
  1. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/Cargo.lock +5 -5
  2. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/Cargo.toml +1 -1
  3. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/PKG-INFO +1 -1
  4. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/pyproject.toml +1 -1
  5. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/rust/crates/synth_gepa/src/codex_app_server.rs +59 -5
  6. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/rust/crates/synth_gepa/src/runtime.rs +15 -1
  7. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/README.md +0 -0
  8. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/rust/crates/synth_gepa/Cargo.toml +0 -0
  9. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/rust/crates/synth_gepa/README.md +0 -0
  10. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/rust/crates/synth_gepa/openapi/gepa-service-v1.yaml +0 -0
  11. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/rust/crates/synth_gepa/src/jesterky_workflow.rs +0 -0
  12. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/rust/crates/synth_gepa/src/lib.rs +0 -0
  13. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/rust/crates/synth_gepa/src/machines.rs +0 -0
  14. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/rust/crates/synth_gepa/src/pipeline.rs +0 -0
  15. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/rust/crates/synth_gepa/src/planner.rs +0 -0
  16. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/rust/crates/synth_gepa/src/prompting_best_practices.md +0 -0
  17. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/rust/crates/synth_gepa/src/service.rs +0 -0
  18. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/rust/crates/synth_optimizer_platform/Cargo.toml +0 -0
  19. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/rust/crates/synth_optimizer_platform/README.md +0 -0
  20. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/rust/crates/synth_optimizer_platform/src/agent_runtime/README.md +0 -0
  21. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/rust/crates/synth_optimizer_platform/src/agent_runtime/app_server.rs +0 -0
  22. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/rust/crates/synth_optimizer_platform/src/agent_runtime/codex_home.rs +0 -0
  23. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/rust/crates/synth_optimizer_platform/src/agent_runtime/daytona.rs +0 -0
  24. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/rust/crates/synth_optimizer_platform/src/agent_runtime/docker.rs +0 -0
  25. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/rust/crates/synth_optimizer_platform/src/agent_runtime/jsonrpc_read_window.rs +0 -0
  26. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/rust/crates/synth_optimizer_platform/src/agent_runtime/limits.rs +0 -0
  27. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/rust/crates/synth_optimizer_platform/src/agent_runtime/local.rs +0 -0
  28. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/rust/crates/synth_optimizer_platform/src/agent_runtime/mod.rs +0 -0
  29. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/rust/crates/synth_optimizer_platform/src/agent_runtime/nano.rs +0 -0
  30. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/rust/crates/synth_optimizer_platform/src/agent_runtime/role_agent.rs +0 -0
  31. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/rust/crates/synth_optimizer_platform/src/agent_runtime/session.rs +0 -0
  32. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/rust/crates/synth_optimizer_platform/src/agent_runtime/substrate.rs +0 -0
  33. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/rust/crates/synth_optimizer_platform/src/agent_runtime/supervisor.rs +0 -0
  34. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/rust/crates/synth_optimizer_platform/src/agent_runtime/usage.rs +0 -0
  35. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/rust/crates/synth_optimizer_platform/src/artifact_store.rs +0 -0
  36. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/rust/crates/synth_optimizer_platform/src/artifacts.rs +0 -0
  37. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/rust/crates/synth_optimizer_platform/src/cache.rs +0 -0
  38. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/rust/crates/synth_optimizer_platform/src/candidates.rs +0 -0
  39. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/rust/crates/synth_optimizer_platform/src/checkpoints.rs +0 -0
  40. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/rust/crates/synth_optimizer_platform/src/config.rs +0 -0
  41. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/rust/crates/synth_optimizer_platform/src/configured_limits.rs +0 -0
  42. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/rust/crates/synth_optimizer_platform/src/container_contract.rs +0 -0
  43. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/rust/crates/synth_optimizer_platform/src/data_models.rs +0 -0
  44. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/rust/crates/synth_optimizer_platform/src/disk_budget.rs +0 -0
  45. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/rust/crates/synth_optimizer_platform/src/error.rs +0 -0
  46. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/rust/crates/synth_optimizer_platform/src/event_visualization.rs +0 -0
  47. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/rust/crates/synth_optimizer_platform/src/events.rs +0 -0
  48. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/rust/crates/synth_optimizer_platform/src/evidence.rs +0 -0
  49. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/rust/crates/synth_optimizer_platform/src/failures.rs +0 -0
  50. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/rust/crates/synth_optimizer_platform/src/fsm.rs +0 -0
  51. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/rust/crates/synth_optimizer_platform/src/http.rs +0 -0
  52. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/rust/crates/synth_optimizer_platform/src/invariants.rs +0 -0
  53. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/rust/crates/synth_optimizer_platform/src/jesterky.rs +0 -0
  54. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/rust/crates/synth_optimizer_platform/src/jobs.rs +0 -0
  55. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/rust/crates/synth_optimizer_platform/src/levers.rs +0 -0
  56. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/rust/crates/synth_optimizer_platform/src/lib.rs +0 -0
  57. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/rust/crates/synth_optimizer_platform/src/limit_engine.rs +0 -0
  58. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/rust/crates/synth_optimizer_platform/src/limits.rs +0 -0
  59. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/rust/crates/synth_optimizer_platform/src/observability.rs +0 -0
  60. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/rust/crates/synth_optimizer_platform/src/operations.rs +0 -0
  61. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/rust/crates/synth_optimizer_platform/src/process.rs +0 -0
  62. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/rust/crates/synth_optimizer_platform/src/projections.rs +0 -0
  63. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/rust/crates/synth_optimizer_platform/src/prompt_program.rs +0 -0
  64. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/rust/crates/synth_optimizer_platform/src/registry.rs +0 -0
  65. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/rust/crates/synth_optimizer_platform/src/resources.rs +0 -0
  66. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/rust/crates/synth_optimizer_platform/src/rollouts.rs +0 -0
  67. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/rust/crates/synth_optimizer_platform/src/runtime_records.rs +0 -0
  68. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/rust/crates/synth_optimizer_platform/src/scores.rs +0 -0
  69. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/rust/crates/synth_optimizer_platform/src/sensors.rs +0 -0
  70. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/rust/crates/synth_optimizer_platform/src/state_machine.rs +0 -0
  71. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/rust/crates/synth_optimizer_platform/src/stopper.rs +0 -0
  72. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/rust/crates/synth_optimizer_platform/src/storage_maintenance.rs +0 -0
  73. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/rust/crates/synth_optimizer_platform/src/usage.rs +0 -0
  74. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/rust/crates/synth_optimizer_platform/src/workspace.rs +0 -0
  75. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/rust/crates/synth_optimizers_py/Cargo.toml +0 -0
  76. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/rust/crates/synth_optimizers_py/README.md +0 -0
  77. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/rust/crates/synth_optimizers_py/src/lib.rs +0 -0
  78. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/src/synth_optimizers/README.md +0 -0
  79. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/src/synth_optimizers/__init__.py +0 -0
  80. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/src/synth_optimizers/_synth_optimizers.pyi +0 -0
  81. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/src/synth_optimizers/board_server.py +0 -0
  82. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/src/synth_optimizers/cli.py +0 -0
  83. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/src/synth_optimizers/discovery.py +0 -0
  84. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/src/synth_optimizers/docs/gelo/00-index.md +0 -0
  85. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/src/synth_optimizers/docs/gelo/10-cli.md +0 -0
  86. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/src/synth_optimizers/docs/gelo/20-sdk.md +0 -0
  87. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/src/synth_optimizers/docs/gelo/30-hosted.md +0 -0
  88. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/src/synth_optimizers/docs/gelo/containers/00-overview.md +0 -0
  89. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/src/synth_optimizers/docs/gelo/containers/20-contract.md +0 -0
  90. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/src/synth_optimizers/docs/gepa/00-index.md +0 -0
  91. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/src/synth_optimizers/docs/gepa/10-cli.md +0 -0
  92. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/src/synth_optimizers/docs/gepa/20-sdk.md +0 -0
  93. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/src/synth_optimizers/docs/gepa/algorithms/00-overview.md +0 -0
  94. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/src/synth_optimizers/docs/gepa/algorithms/10-pipeline-modes.md +0 -0
  95. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/src/synth_optimizers/docs/gepa/algorithms/20-proposer-and-policies.md +0 -0
  96. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/src/synth_optimizers/docs/gepa/assets/synth-logo.png +0 -0
  97. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/src/synth_optimizers/docs/gepa/containers/00-overview.md +0 -0
  98. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/src/synth_optimizers/docs/gepa/containers/10-catalog.md +0 -0
  99. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/src/synth_optimizers/docs/gepa/containers/20-contract.md +0 -0
  100. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/src/synth_optimizers/docs_server.py +0 -0
  101. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/src/synth_optimizers/eval_stats.py +0 -0
  102. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/src/synth_optimizers/gelo.py +0 -0
  103. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/src/synth_optimizers/gepa.py +0 -0
  104. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/src/synth_optimizers/hosted.py +0 -0
  105. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/src/synth_optimizers/hosted_config.py +0 -0
  106. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/src/synth_optimizers/o11y.py +0 -0
  107. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/src/synth_optimizers/observability.py +0 -0
  108. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/src/synth_optimizers/py.typed +0 -0
  109. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/src/synth_optimizers/sdk.py +0 -0
  110. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/src/synth_optimizers/tunnels.py +0 -0
  111. {synth_optimizers-0.2.7.dev20260814 → synth_optimizers-0.2.8.dev20260814}/src/synth_optimizers/victorialogs.py +0 -0
@@ -1306,7 +1306,7 @@ dependencies = [
1306
1306
 
1307
1307
  [[package]]
1308
1308
  name = "synth_gepa"
1309
- version = "0.2.7"
1309
+ version = "0.2.8"
1310
1310
  dependencies = [
1311
1311
  "base64",
1312
1312
  "fs2",
@@ -1321,7 +1321,7 @@ dependencies = [
1321
1321
 
1322
1322
  [[package]]
1323
1323
  name = "synth_mapo"
1324
- version = "0.2.7"
1324
+ version = "0.2.8"
1325
1325
  dependencies = [
1326
1326
  "serde",
1327
1327
  "serde_json",
@@ -1333,7 +1333,7 @@ dependencies = [
1333
1333
 
1334
1334
  [[package]]
1335
1335
  name = "synth_marl_promptopt"
1336
- version = "0.2.7"
1336
+ version = "0.2.8"
1337
1337
  dependencies = [
1338
1338
  "clap",
1339
1339
  "serde",
@@ -1347,7 +1347,7 @@ dependencies = [
1347
1347
 
1348
1348
  [[package]]
1349
1349
  name = "synth_optimizer_platform"
1350
- version = "0.2.7"
1350
+ version = "0.2.8"
1351
1351
  dependencies = [
1352
1352
  "fs2",
1353
1353
  "libc",
@@ -1364,7 +1364,7 @@ dependencies = [
1364
1364
 
1365
1365
  [[package]]
1366
1366
  name = "synth_optimizers_py"
1367
- version = "0.2.7"
1367
+ version = "0.2.8"
1368
1368
  dependencies = [
1369
1369
  "pyo3",
1370
1370
  "serde_json",
@@ -3,7 +3,7 @@ members = ["rust/crates/synth_optimizer_platform", "rust/crates/synth_gepa", "ru
3
3
  resolver = "2"
4
4
 
5
5
  [workspace.package]
6
- version = "0.2.7"
6
+ version = "0.2.8"
7
7
  edition = "2021"
8
8
  license = "Apache-2.0"
9
9
  authors = ["Synth Laboratories <josh@usesynth.ai>"]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: synth-optimizers
3
- Version: 0.2.7.dev20260814
3
+ Version: 0.2.8.dev20260814
4
4
  Requires-Dist: pydantic>=2.0.0
5
5
  Requires-Dist: synth-containers==0.4.1.dev20260814
6
6
  Requires-Dist: websocket-client>=1.8.0
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "synth-optimizers"
3
- version = "0.2.7.dev20260814"
3
+ version = "0.2.8.dev20260814"
4
4
  description = "Public Synth optimizer tooling with a Rust GEPA core."
5
5
  authors = [{name = "Synth Laboratories", email = "josh@usesynth.ai"}]
6
6
  readme = "README.md"
@@ -10,10 +10,10 @@ use reqwest::blocking::Client;
10
10
  use serde_json::{json, Map, Value};
11
11
  use synth_optimizer_platform::{
12
12
  jesterky_workspace_read_model, looks_like_jesterky_manifest,
13
- proposer_delta_chunks_from_protocol, read_jesterky_manifest, record_manifest_validation,
14
- run_turn, AgentTurnOutcome, CodexTurnRequest, NanoAgentTurnIdentity, NanoCodexExecution,
15
- NanoCodexSessionPool, NanoCodexTurnRequest, OptimizerError, PromptProgram, Result,
16
- SynthOptimizerConfig,
13
+ proposer_delta_chunks_from_protocol, proposer_uses_chatgpt_auth, read_jesterky_manifest,
14
+ record_manifest_validation, run_turn, AgentTurnOutcome, CodexTurnRequest,
15
+ NanoAgentTurnIdentity, NanoCodexExecution, NanoCodexSessionPool, NanoCodexTurnRequest,
16
+ OptimizerError, PromptProgram, Result, SynthOptimizerConfig,
17
17
  };
18
18
 
19
19
  const GEPA_REFLECTIVE_FRAME_SCHEMA_VERSION: &str = "gepa_reflective_frame.v1";
@@ -556,7 +556,26 @@ fn normalize_proposer_usage(config: &SynthOptimizerConfig, model: &str, usage: V
556
556
  let provider = config.proposer.provider.trim().to_ascii_lowercase();
557
557
  let model_lower = model.trim().to_ascii_lowercase();
558
558
  let reported_cost = usage_f64_from_map(&usage_map, "cost_usd")
559
- .filter(|value| value.is_finite() && *value > 0.0);
559
+ .filter(|value| value.is_finite() && *value >= 0.0);
560
+ if proposer_uses_chatgpt_auth(&config.proposer.auth_mode) {
561
+ usage_map.insert(
562
+ "provider".to_string(),
563
+ Value::String("chatgpt_subscription".to_string()),
564
+ );
565
+ usage_map.insert("model".to_string(), Value::String(model.to_string()));
566
+ if reported_cost.is_none() {
567
+ // ChatGPT-authenticated Codex turns are subscription-backed rather
568
+ // than metered API calls. Record an explicit zero incremental API
569
+ // charge so the hard cost ledger does not mistake the absence of
570
+ // an API receipt for unknown spend.
571
+ usage_map.insert("cost_usd".to_string(), json!(0.0));
572
+ usage_map.insert(
573
+ "cost_source".to_string(),
574
+ Value::String("chatgpt_subscription_no_incremental_api_charge".to_string()),
575
+ );
576
+ }
577
+ return Value::Object(usage_map);
578
+ }
560
579
  if provider.eq_ignore_ascii_case("openrouter") && model_lower == OPENROUTER_GROK43_MODEL {
561
580
  return normalize_openrouter_grok43_usage(model, usage_map);
562
581
  }
@@ -3378,3 +3397,38 @@ fn non_empty(value: Option<&str>) -> Option<&str> {
3378
3397
  Some(value)
3379
3398
  }
3380
3399
  }
3400
+
3401
+ #[cfg(test)]
3402
+ mod cost_tests {
3403
+ use super::*;
3404
+
3405
+ #[test]
3406
+ fn chatgpt_proposer_emits_explicit_zero_incremental_api_cost() {
3407
+ let mut config = SynthOptimizerConfig::default();
3408
+ config.proposer.auth_mode = "chatgpt".to_string();
3409
+ let usage = normalize_proposer_usage(
3410
+ &config,
3411
+ "gpt-5.6-luna",
3412
+ json!({"prompt_tokens": 100, "completion_tokens": 20, "total_tokens": 120}),
3413
+ );
3414
+ assert_eq!(usage.get("cost_usd"), Some(&json!(0.0)));
3415
+ assert_eq!(
3416
+ usage.get("cost_source"),
3417
+ Some(&json!("chatgpt_subscription_no_incremental_api_charge"))
3418
+ );
3419
+ assert_eq!(usage.get("provider"), Some(&json!("chatgpt_subscription")));
3420
+ }
3421
+
3422
+ #[test]
3423
+ fn chatgpt_proposer_preserves_an_explicit_cost_receipt() {
3424
+ let mut config = SynthOptimizerConfig::default();
3425
+ config.proposer.auth_mode = "chatgpt".to_string();
3426
+ let usage = normalize_proposer_usage(
3427
+ &config,
3428
+ "gpt-5.6-luna",
3429
+ json!({"cost_usd": 0.25, "cost_source": "provider"}),
3430
+ );
3431
+ assert_eq!(usage.get("cost_usd"), Some(&json!(0.25)));
3432
+ assert_eq!(usage.get("cost_source"), Some(&json!("provider")));
3433
+ }
3434
+ }
@@ -509,6 +509,7 @@ impl<'a> GepaRuntimeExecutor<'a> {
509
509
  json!(self.config.gepa.rollout_submission_mode),
510
510
  );
511
511
  }
512
+ persist_runtime_outcome_before_completion(self.workspace, run_id, job_id, &outcome)?;
512
513
  record_runtime_effect_completed(
513
514
  self.workspace,
514
515
  RuntimeEffectCompletionInput {
@@ -666,7 +667,7 @@ impl<'a> GepaRuntimeExecutor<'a> {
666
667
  .and_then(|usage| usage.get("cost_usd"))
667
668
  .or_else(|| response.get("cost_usd"))
668
669
  .and_then(Value::as_f64)
669
- .filter(|value| value.is_finite() && *value > 0.0)
670
+ .filter(|value| value.is_finite() && *value >= 0.0)
670
671
  .or_else(|| proposer_static_cost_usd(self.config, &usage, &response));
671
672
  let cost_usd = reported_cost_usd.unwrap_or(0.0);
672
673
  let backend = response
@@ -1566,6 +1567,19 @@ fn ensure_job_lease(
1566
1567
  Ok(())
1567
1568
  }
1568
1569
 
1570
+ fn persist_runtime_outcome_before_completion(
1571
+ workspace: &WorkspaceStore,
1572
+ run_id: &str,
1573
+ job_id: &str,
1574
+ outcome: &RuntimeEffectOutcome,
1575
+ ) -> Result<()> {
1576
+ let stored = crate::stored_runtime_outcome(outcome)?;
1577
+ let mut job = workspace.optimizer_job(run_id, job_id)?;
1578
+ job.payload
1579
+ .insert("runtime_outcome".to_string(), serde_json::to_value(stored)?);
1580
+ workspace.record_optimizer_job(&job)
1581
+ }
1582
+
1569
1583
  fn runtime_lease_id(worker_id: &str, job_id: &str) -> String {
1570
1584
  format!("lease_{worker_id}_{job_id}_{}", now_millis())
1571
1585
  }