tokenjam 0.7.0__tar.gz → 0.7.1__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 (847) hide show
  1. {tokenjam-0.7.0 → tokenjam-0.7.1}/.claude/rules/core-architecture.md +1 -1
  2. {tokenjam-0.7.0 → tokenjam-0.7.1}/.claude/rules/web-ui.md +5 -2
  3. {tokenjam-0.7.0 → tokenjam-0.7.1}/.github/scripts/archive_traffic.py +6 -2
  4. {tokenjam-0.7.0 → tokenjam-0.7.1}/.github/workflows/traffic-archive.yml +48 -3
  5. {tokenjam-0.7.0 → tokenjam-0.7.1}/PKG-INFO +8 -2
  6. {tokenjam-0.7.0 → tokenjam-0.7.1}/README.md +7 -1
  7. tokenjam-0.7.1/RELEASE_NOTES_0.7.0.md +113 -0
  8. {tokenjam-0.7.0 → tokenjam-0.7.1}/docs/alerts.md +52 -1
  9. {tokenjam-0.7.0 → tokenjam-0.7.1}/docs/architecture.md +84 -2
  10. {tokenjam-0.7.0 → tokenjam-0.7.1}/docs/backfill/langfuse.md +7 -5
  11. {tokenjam-0.7.0 → tokenjam-0.7.1}/docs/cli-reference.md +84 -3
  12. {tokenjam-0.7.0 → tokenjam-0.7.1}/docs/configuration.md +7 -1
  13. {tokenjam-0.7.0 → tokenjam-0.7.1}/docs/first-hour.md +20 -7
  14. tokenjam-0.7.1/docs/ledger/cloud-bridge.md +106 -0
  15. tokenjam-0.7.1/docs/ledger/hooks-and-notes.md +129 -0
  16. tokenjam-0.7.1/docs/ledger/overview.md +135 -0
  17. {tokenjam-0.7.0 → tokenjam-0.7.1}/docs/nemoclaw-integration.md +1 -1
  18. {tokenjam-0.7.0 → tokenjam-0.7.1}/docs/optimize/shipped.md +13 -1
  19. {tokenjam-0.7.0 → tokenjam-0.7.1}/docs/optimize/verbosity.md +9 -7
  20. {tokenjam-0.7.0 → tokenjam-0.7.1}/growth/README.md +22 -0
  21. {tokenjam-0.7.0 → tokenjam-0.7.1}/npm-wrapper/package.json +1 -1
  22. {tokenjam-0.7.0 → tokenjam-0.7.1}/plugin/.claude-plugin/plugin.json +1 -1
  23. {tokenjam-0.7.0 → tokenjam-0.7.1}/pyproject.toml +1 -1
  24. {tokenjam-0.7.0 → tokenjam-0.7.1}/sdk-ts/package.json +1 -1
  25. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/integration/test_api.py +19 -0
  26. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/integration/test_cli.py +117 -1
  27. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/integration/test_cost_attribution.py +72 -0
  28. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/integration/test_db.py +22 -0
  29. tokenjam-0.7.1/tests/integration/test_full_pipeline.py +1379 -0
  30. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/integration/test_storage_backend_parity.py +44 -0
  31. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/rate_bands.py +5 -4
  32. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/synthetic/test_ingest.py +314 -24
  33. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_advertised_commands_are_invocable.py +1 -0
  34. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_api_backend_span_deserialize.py +2 -1
  35. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_cmd_policy.py +18 -0
  36. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_config.py +18 -0
  37. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_context_diagnostic.py +25 -5
  38. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_cost.py +7 -6
  39. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_db_helpers.py +11 -0
  40. tokenjam-0.7.1/tests/unit/test_doctor_paths.py +184 -0
  41. tokenjam-0.7.1/tests/unit/test_doctor_unattributed_spend.py +56 -0
  42. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_framing.py +14 -0
  43. tokenjam-0.7.1/tests/unit/test_http_exporter_auth.py +199 -0
  44. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_ingest_langfuse.py +194 -0
  45. tokenjam-0.7.1/tests/unit/test_lens_unattributed_spend.py +50 -0
  46. tokenjam-0.7.1/tests/unit/test_mast_channel.py +283 -0
  47. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_optimize_verbosity.py +144 -0
  48. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_pricing_axes.py +13 -10
  49. tokenjam-0.7.1/tests/unit/test_pricing_current_lineup.py +205 -0
  50. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_provider_attribution.py +54 -1
  51. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_quickstart.py +14 -0
  52. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_schema_self_heal.py +1 -1
  53. tokenjam-0.7.1/tests/unit/test_ui_index_reload.py +143 -0
  54. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/api/app.py +35 -4
  55. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/api/routes/cost.py +9 -0
  56. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/api/routes/sessions.py +2 -0
  57. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/api/routes/status.py +10 -0
  58. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/api/routes/traces.py +1 -0
  59. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/cli/cmd_backfill.py +42 -2
  60. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/cli/cmd_cost.py +37 -3
  61. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/cli/cmd_doctor.py +71 -6
  62. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/cli/cmd_optimize.py +16 -4
  63. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/cli/cmd_policy.py +7 -0
  64. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/cli/cmd_status.py +25 -2
  65. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/alerts.py +111 -8
  66. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/api_backend.py +30 -0
  67. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/config.py +7 -0
  68. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/context_diagnostic.py +6 -0
  69. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/cost.py +5 -4
  70. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/db.py +352 -20
  71. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/framing.py +1 -1
  72. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/ingest.py +197 -15
  73. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/ingest_adapters/langfuse.py +97 -34
  74. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/models.py +5 -1
  75. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/session_timeline.py +1 -1
  76. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/otel/provider.py +38 -1
  77. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/pricing/models.toml +339 -20
  78. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/sdk/bootstrap.py +9 -4
  79. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/sdk/http_exporter.py +24 -6
  80. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/ui/index.html +24 -2
  81. tokenjam-0.7.0/tests/integration/test_full_pipeline.py +0 -422
  82. tokenjam-0.7.0/tests/unit/test_doctor_paths.py +0 -53
  83. tokenjam-0.7.0/tests/unit/test_http_exporter_auth.py +0 -45
  84. {tokenjam-0.7.0 → tokenjam-0.7.1}/.claude/rules/alerts.md +0 -0
  85. {tokenjam-0.7.0 → tokenjam-0.7.1}/.claude/rules/api.md +0 -0
  86. {tokenjam-0.7.0 → tokenjam-0.7.1}/.claude/rules/cli-output.md +0 -0
  87. {tokenjam-0.7.0 → tokenjam-0.7.1}/.claude/rules/config-toml.md +0 -0
  88. {tokenjam-0.7.0 → tokenjam-0.7.1}/.claude/rules/core-config-pricing.md +0 -0
  89. {tokenjam-0.7.0 → tokenjam-0.7.1}/.claude/rules/examples-and-incidents.md +0 -0
  90. {tokenjam-0.7.0 → tokenjam-0.7.1}/.claude/rules/growth-instrumentation.md +0 -0
  91. {tokenjam-0.7.0 → tokenjam-0.7.1}/.claude/rules/ingest-accounting.md +0 -0
  92. {tokenjam-0.7.0 → tokenjam-0.7.1}/.claude/rules/onboarding-dotfiles.md +0 -0
  93. {tokenjam-0.7.0 → tokenjam-0.7.1}/.claude/rules/optimize-analyzers.md +0 -0
  94. {tokenjam-0.7.0 → tokenjam-0.7.1}/.claude/rules/optimize-architecture.md +0 -0
  95. {tokenjam-0.7.0 → tokenjam-0.7.1}/.claude/rules/optimize-cost-figures.md +0 -0
  96. {tokenjam-0.7.0 → tokenjam-0.7.1}/.claude/rules/otel.md +0 -0
  97. {tokenjam-0.7.0 → tokenjam-0.7.1}/.claude/rules/release.md +0 -0
  98. {tokenjam-0.7.0 → tokenjam-0.7.1}/.claude/rules/sdk.md +0 -0
  99. {tokenjam-0.7.0 → tokenjam-0.7.1}/.claude/rules/tests.md +0 -0
  100. {tokenjam-0.7.0 → tokenjam-0.7.1}/.claude-plugin/marketplace.json +0 -0
  101. {tokenjam-0.7.0 → tokenjam-0.7.1}/.dockerignore +0 -0
  102. {tokenjam-0.7.0 → tokenjam-0.7.1}/.github/CODEOWNERS +0 -0
  103. {tokenjam-0.7.0 → tokenjam-0.7.1}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  104. {tokenjam-0.7.0 → tokenjam-0.7.1}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  105. {tokenjam-0.7.0 → tokenjam-0.7.1}/.github/ISSUE_TEMPLATE/integration_request.md +0 -0
  106. {tokenjam-0.7.0 → tokenjam-0.7.1}/.github/actions/docker-publish/action.yml +0 -0
  107. {tokenjam-0.7.0 → tokenjam-0.7.1}/.github/pull_request_template.md +0 -0
  108. {tokenjam-0.7.0 → tokenjam-0.7.1}/.github/scripts/contributor_label_guard.py +0 -0
  109. {tokenjam-0.7.0 → tokenjam-0.7.1}/.github/workflows/ci.yml +0 -0
  110. {tokenjam-0.7.0 → tokenjam-0.7.1}/.github/workflows/contributor-label-guard.yml +0 -0
  111. {tokenjam-0.7.0 → tokenjam-0.7.1}/.github/workflows/docker-publish.yml +0 -0
  112. {tokenjam-0.7.0 → tokenjam-0.7.1}/.github/workflows/publish-npm.yml +0 -0
  113. {tokenjam-0.7.0 → tokenjam-0.7.1}/.github/workflows/publish-pypi.yml +0 -0
  114. {tokenjam-0.7.0 → tokenjam-0.7.1}/.gitignore +0 -0
  115. {tokenjam-0.7.0 → tokenjam-0.7.1}/AGENTS.md +0 -0
  116. {tokenjam-0.7.0 → tokenjam-0.7.1}/CLAUDE.md +0 -0
  117. {tokenjam-0.7.0 → tokenjam-0.7.1}/CODE_OF_CONDUCT.md +0 -0
  118. {tokenjam-0.7.0 → tokenjam-0.7.1}/CONTRIBUTING.md +0 -0
  119. {tokenjam-0.7.0 → tokenjam-0.7.1}/Dockerfile +0 -0
  120. {tokenjam-0.7.0 → tokenjam-0.7.1}/LICENSE +0 -0
  121. {tokenjam-0.7.0 → tokenjam-0.7.1}/Makefile +0 -0
  122. {tokenjam-0.7.0 → tokenjam-0.7.1}/SECURITY.md +0 -0
  123. {tokenjam-0.7.0 → tokenjam-0.7.1}/docs/agent-capability-matrix.md +0 -0
  124. {tokenjam-0.7.0 → tokenjam-0.7.1}/docs/assets/tj-quickstart-hero.png +0 -0
  125. {tokenjam-0.7.0 → tokenjam-0.7.1}/docs/assets/tokenjam-2d.png +0 -0
  126. {tokenjam-0.7.0 → tokenjam-0.7.1}/docs/assets/tokenjam-dashboard.png +0 -0
  127. {tokenjam-0.7.0 → tokenjam-0.7.1}/docs/assets/tokenjam-flow-band.svg +0 -0
  128. {tokenjam-0.7.0 → tokenjam-0.7.1}/docs/assets/tokenjam-token-flow.png +0 -0
  129. {tokenjam-0.7.0 → tokenjam-0.7.1}/docs/assets/tokenjam-waste-grid.svg +0 -0
  130. {tokenjam-0.7.0 → tokenjam-0.7.1}/docs/backfill/codex.md +0 -0
  131. {tokenjam-0.7.0 → tokenjam-0.7.1}/docs/backfill/helicone.md +0 -0
  132. {tokenjam-0.7.0 → tokenjam-0.7.1}/docs/backfill/otlp.md +0 -0
  133. {tokenjam-0.7.0 → tokenjam-0.7.1}/docs/backfill/overview.md +0 -0
  134. {tokenjam-0.7.0 → tokenjam-0.7.1}/docs/brand/README.md +0 -0
  135. {tokenjam-0.7.0 → tokenjam-0.7.1}/docs/brand/tokenjam-banner.png +0 -0
  136. {tokenjam-0.7.0 → tokenjam-0.7.1}/docs/brand/tokenjam-banner.svg +0 -0
  137. {tokenjam-0.7.0 → tokenjam-0.7.1}/docs/brand/tokenjam-icon.png +0 -0
  138. {tokenjam-0.7.0 → tokenjam-0.7.1}/docs/brand/tokenjam-icon.svg +0 -0
  139. {tokenjam-0.7.0 → tokenjam-0.7.1}/docs/brand/tokenjam-repo-header.png +0 -0
  140. {tokenjam-0.7.0 → tokenjam-0.7.1}/docs/brand/tokenjam-wordmark.png +0 -0
  141. {tokenjam-0.7.0 → tokenjam-0.7.1}/docs/brand/tokenjam-wordmark.svg +0 -0
  142. {tokenjam-0.7.0 → tokenjam-0.7.1}/docs/claude-code-integration.md +0 -0
  143. {tokenjam-0.7.0 → tokenjam-0.7.1}/docs/export.md +0 -0
  144. {tokenjam-0.7.0 → tokenjam-0.7.1}/docs/framework-support.md +0 -0
  145. {tokenjam-0.7.0 → tokenjam-0.7.1}/docs/getting-started.md +0 -0
  146. {tokenjam-0.7.0 → tokenjam-0.7.1}/docs/harness-integration.md +0 -0
  147. {tokenjam-0.7.0 → tokenjam-0.7.1}/docs/installation.md +0 -0
  148. {tokenjam-0.7.0 → tokenjam-0.7.1}/docs/internal/close-the-loop.md +0 -0
  149. {tokenjam-0.7.0 → tokenjam-0.7.1}/docs/internal/lens-vendor-versions.md +0 -0
  150. {tokenjam-0.7.0 → tokenjam-0.7.1}/docs/internal/release-smoke-checklist.md +0 -0
  151. {tokenjam-0.7.0 → tokenjam-0.7.1}/docs/internal/repeat-task-codification-measurement.md +0 -0
  152. {tokenjam-0.7.0 → tokenjam-0.7.1}/docs/internal/specs/.gitkeep +0 -0
  153. {tokenjam-0.7.0 → tokenjam-0.7.1}/docs/internal/specs/map-board-direction.md +0 -0
  154. {tokenjam-0.7.0 → tokenjam-0.7.1}/docs/openclaw.md +0 -0
  155. {tokenjam-0.7.0 → tokenjam-0.7.1}/docs/optimize/cache.md +0 -0
  156. {tokenjam-0.7.0 → tokenjam-0.7.1}/docs/optimize/downsize.md +0 -0
  157. {tokenjam-0.7.0 → tokenjam-0.7.1}/docs/optimize/reuse.md +0 -0
  158. {tokenjam-0.7.0 → tokenjam-0.7.1}/docs/optimize/script.md +0 -0
  159. {tokenjam-0.7.0 → tokenjam-0.7.1}/docs/optimize/subagent.md +0 -0
  160. {tokenjam-0.7.0 → tokenjam-0.7.1}/docs/optimize/trim.md +0 -0
  161. {tokenjam-0.7.0 → tokenjam-0.7.1}/docs/policy/overview.md +0 -0
  162. {tokenjam-0.7.0 → tokenjam-0.7.1}/docs/proxy/overview.md +0 -0
  163. {tokenjam-0.7.0 → tokenjam-0.7.1}/docs/python-sdk.md +0 -0
  164. {tokenjam-0.7.0 → tokenjam-0.7.1}/docs/screenshots/tj-budget.png +0 -0
  165. {tokenjam-0.7.0 → tokenjam-0.7.1}/docs/screenshots/tj-cost.png +0 -0
  166. {tokenjam-0.7.0 → tokenjam-0.7.1}/docs/screenshots/tj-dashboard-leaderboard.png +0 -0
  167. {tokenjam-0.7.0 → tokenjam-0.7.1}/docs/screenshots/tj-dashboard-tools.png +0 -0
  168. {tokenjam-0.7.0 → tokenjam-0.7.1}/docs/screenshots/tj-dashboard.png +0 -0
  169. {tokenjam-0.7.0 → tokenjam-0.7.1}/docs/screenshots/tj-status.png +0 -0
  170. {tokenjam-0.7.0 → tokenjam-0.7.1}/docs/screenshots/tj-traces.png +0 -0
  171. {tokenjam-0.7.0 → tokenjam-0.7.1}/docs/typescript-sdk.md +0 -0
  172. {tokenjam-0.7.0 → tokenjam-0.7.1}/examples/README.md +0 -0
  173. {tokenjam-0.7.0 → tokenjam-0.7.1}/examples/alerts_and_drift/_shared.py +0 -0
  174. {tokenjam-0.7.0 → tokenjam-0.7.1}/examples/alerts_and_drift/budget_breach_demo.py +0 -0
  175. {tokenjam-0.7.0 → tokenjam-0.7.1}/examples/alerts_and_drift/drift_demo.py +0 -0
  176. {tokenjam-0.7.0 → tokenjam-0.7.1}/examples/alerts_and_drift/record_outcome_demo.py +0 -0
  177. {tokenjam-0.7.0 → tokenjam-0.7.1}/examples/alerts_and_drift/sensitive_actions_demo.py +0 -0
  178. {tokenjam-0.7.0 → tokenjam-0.7.1}/examples/multi/rag_pipeline.py +0 -0
  179. {tokenjam-0.7.0 → tokenjam-0.7.1}/examples/multi/research_team.py +0 -0
  180. {tokenjam-0.7.0 → tokenjam-0.7.1}/examples/multi/router_agent.py +0 -0
  181. {tokenjam-0.7.0 → tokenjam-0.7.1}/examples/multi/sample_docs/agent_patterns.txt +0 -0
  182. {tokenjam-0.7.0 → tokenjam-0.7.1}/examples/multi/sample_docs/cost_management.txt +0 -0
  183. {tokenjam-0.7.0 → tokenjam-0.7.1}/examples/multi/sample_docs/observability.txt +0 -0
  184. {tokenjam-0.7.0 → tokenjam-0.7.1}/examples/multi/sample_docs/safety.txt +0 -0
  185. {tokenjam-0.7.0 → tokenjam-0.7.1}/examples/openclaw/README.md +0 -0
  186. {tokenjam-0.7.0 → tokenjam-0.7.1}/examples/single_framework/autogen_agent.py +0 -0
  187. {tokenjam-0.7.0 → tokenjam-0.7.1}/examples/single_framework/crewai_agent.py +0 -0
  188. {tokenjam-0.7.0 → tokenjam-0.7.1}/examples/single_framework/langchain_agent.py +0 -0
  189. {tokenjam-0.7.0 → tokenjam-0.7.1}/examples/single_framework/langgraph_agent.py +0 -0
  190. {tokenjam-0.7.0 → tokenjam-0.7.1}/examples/single_framework/llamaindex_agent.py +0 -0
  191. {tokenjam-0.7.0 → tokenjam-0.7.1}/examples/single_provider/anthropic_agent.py +0 -0
  192. {tokenjam-0.7.0 → tokenjam-0.7.1}/examples/single_provider/bedrock_agent.py +0 -0
  193. {tokenjam-0.7.0 → tokenjam-0.7.1}/examples/single_provider/gemini_agent.py +0 -0
  194. {tokenjam-0.7.0 → tokenjam-0.7.1}/examples/single_provider/litellm_agent.py +0 -0
  195. {tokenjam-0.7.0 → tokenjam-0.7.1}/examples/single_provider/openai_agent.py +0 -0
  196. {tokenjam-0.7.0 → tokenjam-0.7.1}/examples/single_provider/openai_agents_sdk_agent.py +0 -0
  197. {tokenjam-0.7.0 → tokenjam-0.7.1}/incidents/hallucination-drift/BLOG.md +0 -0
  198. {tokenjam-0.7.0 → tokenjam-0.7.1}/incidents/hallucination-drift/README.md +0 -0
  199. {tokenjam-0.7.0 → tokenjam-0.7.1}/incidents/hallucination-drift/scenario.py +0 -0
  200. {tokenjam-0.7.0 → tokenjam-0.7.1}/incidents/retry-loop/BLOG.md +0 -0
  201. {tokenjam-0.7.0 → tokenjam-0.7.1}/incidents/retry-loop/README.md +0 -0
  202. {tokenjam-0.7.0 → tokenjam-0.7.1}/incidents/retry-loop/scenario.py +0 -0
  203. {tokenjam-0.7.0 → tokenjam-0.7.1}/incidents/surprise-cost/BLOG.md +0 -0
  204. {tokenjam-0.7.0 → tokenjam-0.7.1}/incidents/surprise-cost/README.md +0 -0
  205. {tokenjam-0.7.0 → tokenjam-0.7.1}/incidents/surprise-cost/scenario.py +0 -0
  206. {tokenjam-0.7.0 → tokenjam-0.7.1}/npm-wrapper/README.md +0 -0
  207. {tokenjam-0.7.0 → tokenjam-0.7.1}/npm-wrapper/bin/tj.js +0 -0
  208. {tokenjam-0.7.0 → tokenjam-0.7.1}/plugin/README.md +0 -0
  209. {tokenjam-0.7.0 → tokenjam-0.7.1}/plugin/commands/doctor.md +0 -0
  210. {tokenjam-0.7.0 → tokenjam-0.7.1}/plugin/commands/onboard.md +0 -0
  211. {tokenjam-0.7.0 → tokenjam-0.7.1}/plugin/commands/optimize.md +0 -0
  212. {tokenjam-0.7.0 → tokenjam-0.7.1}/plugin/commands/status.md +0 -0
  213. {tokenjam-0.7.0 → tokenjam-0.7.1}/plugin/commands/uninstall.md +0 -0
  214. {tokenjam-0.7.0 → tokenjam-0.7.1}/scripts/release.sh +0 -0
  215. {tokenjam-0.7.0 → tokenjam-0.7.1}/sdk-ts/README.md +0 -0
  216. {tokenjam-0.7.0 → tokenjam-0.7.1}/sdk-ts/examples/record-outcome.ts +0 -0
  217. {tokenjam-0.7.0 → tokenjam-0.7.1}/sdk-ts/package-lock.json +0 -0
  218. {tokenjam-0.7.0 → tokenjam-0.7.1}/sdk-ts/src/client.test.ts +0 -0
  219. {tokenjam-0.7.0 → tokenjam-0.7.1}/sdk-ts/src/client.ts +0 -0
  220. {tokenjam-0.7.0 → tokenjam-0.7.1}/sdk-ts/src/index.ts +0 -0
  221. {tokenjam-0.7.0 → tokenjam-0.7.1}/sdk-ts/src/record-outcome.test.ts +0 -0
  222. {tokenjam-0.7.0 → tokenjam-0.7.1}/sdk-ts/src/semconv.test.ts +0 -0
  223. {tokenjam-0.7.0 → tokenjam-0.7.1}/sdk-ts/src/semconv.ts +0 -0
  224. {tokenjam-0.7.0 → tokenjam-0.7.1}/sdk-ts/src/span-builder.test.ts +0 -0
  225. {tokenjam-0.7.0 → tokenjam-0.7.1}/sdk-ts/src/span-builder.ts +0 -0
  226. {tokenjam-0.7.0 → tokenjam-0.7.1}/sdk-ts/src/types.ts +0 -0
  227. {tokenjam-0.7.0 → tokenjam-0.7.1}/sdk-ts/tsconfig.json +0 -0
  228. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/__init__.py +0 -0
  229. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/agent-post-release-runner.md +0 -0
  230. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/agent-pre-release-runner.md +0 -0
  231. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/agents/__init__.py +0 -0
  232. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/agents/email_agent_budget_breach.py +0 -0
  233. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/agents/email_agent_drift.py +0 -0
  234. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/agents/email_agent_loop.py +0 -0
  235. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/agents/email_agent_normal.py +0 -0
  236. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/agents/mock_llm.py +0 -0
  237. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/agents/test_mock_scenarios.py +0 -0
  238. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/agents/test_record_outcome.py +0 -0
  239. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/conftest.py +0 -0
  240. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/e2e/__init__.py +0 -0
  241. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/e2e/conftest.py +0 -0
  242. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/e2e/test_real_llm.py +0 -0
  243. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/factories.py +0 -0
  244. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/fixtures/helicone_real_response.json +0 -0
  245. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/fixtures/langfuse_real_response.json +0 -0
  246. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/fixtures/otlp_sample.json +0 -0
  247. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/integration/__init__.py +0 -0
  248. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/integration/test_agents_and_tenants_dual_units.py +0 -0
  249. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/integration/test_analytics.py +0 -0
  250. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/integration/test_analyzers_off_the_request_path.py +0 -0
  251. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/integration/test_cli_api_framing_parity.py +0 -0
  252. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/integration/test_cli_uninstall.py +0 -0
  253. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/integration/test_cmd_proxy.py +0 -0
  254. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/integration/test_cmd_route.py +0 -0
  255. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/integration/test_context_serve.py +0 -0
  256. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/integration/test_cost_charts.py +0 -0
  257. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/integration/test_cost_compare_serve.py +0 -0
  258. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/integration/test_cost_components_reconcile.py +0 -0
  259. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/integration/test_cost_components_recoverable_population.py +0 -0
  260. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/integration/test_cost_framing_window.py +0 -0
  261. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/integration/test_cost_proposals_api.py +0 -0
  262. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/integration/test_daemon_lock_paths_770.py +0 -0
  263. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/integration/test_data_access_parity.py +0 -0
  264. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/integration/test_demo_live.py +0 -0
  265. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/integration/test_demos.py +0 -0
  266. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/integration/test_first_run_roundtrip_239.py +0 -0
  267. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/integration/test_global_json_flag.py +0 -0
  268. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/integration/test_inbox_headline_total_api.py +0 -0
  269. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/integration/test_litellm_enrichment.py +0 -0
  270. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/integration/test_logs_api.py +0 -0
  271. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/integration/test_policy_api.py +0 -0
  272. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/integration/test_proxy_app.py +0 -0
  273. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/integration/test_proxy_policy.py +0 -0
  274. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/integration/test_quota_audit_serve.py +0 -0
  275. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/integration/test_relearn_api.py +0 -0
  276. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/integration/test_relearn_window_api.py +0 -0
  277. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/integration/test_rules_surface.py +0 -0
  278. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/integration/test_sdk_config_discovery.py +0 -0
  279. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/integration/test_summarize_api.py +0 -0
  280. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/integration/test_summarize_cli.py +0 -0
  281. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/integration/test_summarize_run_api.py +0 -0
  282. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/integration/test_tokenmaxx_serve.py +0 -0
  283. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/integration/test_trace_detail_payload.py +0 -0
  284. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/integration/test_xdist_isolation.py +0 -0
  285. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/ledger_fixtures.py +0 -0
  286. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/manual-new-release-tests.md +0 -0
  287. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/manual-pre-release-testing.md +0 -0
  288. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/summarize_fakes.py +0 -0
  289. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/synthetic/__init__.py +0 -0
  290. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/synthetic/test_alert_engine_restart.py +0 -0
  291. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/synthetic/test_alert_rules.py +0 -0
  292. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/synthetic/test_async_hooks_concurrency.py +0 -0
  293. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/synthetic/test_cost_tracking.py +0 -0
  294. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/synthetic/test_drift_detection.py +0 -0
  295. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/synthetic/test_request_capture.py +0 -0
  296. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/synthetic/test_schema_validation.py +0 -0
  297. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/token_aggregate_guard.py +0 -0
  298. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/toy_agent/toy_agent.py +0 -0
  299. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/__init__.py +0 -0
  300. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_agent_config.py +0 -0
  301. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_agent_kind.py +0 -0
  302. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_alerts.py +0 -0
  303. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_analysis_span_retention.py +0 -0
  304. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_analytics_metric_expr.py +0 -0
  305. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_analyzer_scope.py +0 -0
  306. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_analyzer_scope_isolation.py +0 -0
  307. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_api_backend_timeout.py +0 -0
  308. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_async_hooks.py +0 -0
  309. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_attribution_cache.py +0 -0
  310. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_backfill.py +0 -0
  311. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_backfill_codex.py +0 -0
  312. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_backfill_interrupted_flush.py +0 -0
  313. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_backfill_progress.py +0 -0
  314. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_batch_placement.py +0 -0
  315. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_budget_cap_policy.py +0 -0
  316. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_budget_group_cost.py +0 -0
  317. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_budget_route.py +0 -0
  318. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_bulk_insert_spans.py +0 -0
  319. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_cache_efficacy.py +0 -0
  320. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_cache_recommend.py +0 -0
  321. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_cache_root_cause.py +0 -0
  322. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_cache_root_cause_proposals.py +0 -0
  323. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_cache_root_cause_render.py +0 -0
  324. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_cli_cloud_init.py +0 -0
  325. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_cli_entrypoint.py +0 -0
  326. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_cli_help_descriptions.py +0 -0
  327. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_cli_palette.py +0 -0
  328. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_cli_status_registry.py +0 -0
  329. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_cloud_sync.py +0 -0
  330. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_cmd_cost.py +0 -0
  331. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_cmd_mcp_config_discovery.py +0 -0
  332. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_cmd_pricing.py +0 -0
  333. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_cmd_resume_brief.py +0 -0
  334. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_cmd_serve_port_precheck.py +0 -0
  335. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_cmd_session_story.py +0 -0
  336. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_cmd_status_ingest_freshness.py +0 -0
  337. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_cmd_status_teaser.py +0 -0
  338. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_cmd_stop.py +0 -0
  339. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_cmd_stop_scoping.py +0 -0
  340. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_cmd_tokenmaxx.py +0 -0
  341. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_cmd_upgrade.py +0 -0
  342. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_commit_hooks.py +0 -0
  343. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_compare.py +0 -0
  344. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_config_discovery_guard.py +0 -0
  345. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_config_secret_divergence.py +0 -0
  346. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_config_write_target.py +0 -0
  347. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_context_resend.py +0 -0
  348. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_contributor_label_guard.py +0 -0
  349. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_cost_accounting_guards.py +0 -0
  350. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_cost_api_recoverable_presentation.py +0 -0
  351. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_cost_compare_framing.py +0 -0
  352. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_cost_proposal_persona_ledger.py +0 -0
  353. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_cost_proposal_verbs.py +0 -0
  354. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_cost_proposals.py +0 -0
  355. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_cost_proposals_model.py +0 -0
  356. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_cross_analyzer_recoverable_invariant.py +0 -0
  357. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_cycle.py +0 -0
  358. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_cycle_provenance_record.py +0 -0
  359. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_dashboard_hero_netted_rollup.py +0 -0
  360. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_data_access.py +0 -0
  361. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_db_close_backfill.py +0 -0
  362. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_db_fatal_invalidation.py +0 -0
  363. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_deadweight.py +0 -0
  364. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_deadweight_apply.py +0 -0
  365. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_deadweight_plugins.py +0 -0
  366. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_delivery_kinds.py +0 -0
  367. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_demo_env.py +0 -0
  368. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_demo_live.py +0 -0
  369. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_demo_packaging.py +0 -0
  370. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_demo_scenarios.py +0 -0
  371. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_distill.py +0 -0
  372. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_doctor_capture_prompts.py +0 -0
  373. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_doctor_content_capture_gap.py +0 -0
  374. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_doctor_corpus_freshness.py +0 -0
  375. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_doctor_daemon_liveness.py +0 -0
  376. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_doctor_first_signal.py +0 -0
  377. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_doctor_ingest_secret.py +0 -0
  378. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_doctor_otlp_endpoint.py +0 -0
  379. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_doctor_spans_indexes.py +0 -0
  380. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_doctor_statusline_wiring.py +0 -0
  381. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_doctor_transcript_gap.py +0 -0
  382. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_downgrade_candidates_priceable.py +0 -0
  383. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_downsize_agent_pricing.py +0 -0
  384. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_downsize_applied_ledger_migration.py +0 -0
  385. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_downsize_driver_role.py +0 -0
  386. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_drift.py +0 -0
  387. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_export_claude_code.py +0 -0
  388. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_export_route_generators.py +0 -0
  389. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_fix_actionability.py +0 -0
  390. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_fix_catalog.py +0 -0
  391. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_fix_grounding.py +0 -0
  392. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_formatting.py +0 -0
  393. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_formatting_capped_table.py +0 -0
  394. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_global_ingest_secret.py +0 -0
  395. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_harness_setup.py +0 -0
  396. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_humanize.py +0 -0
  397. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_inbox_contribution.py +0 -0
  398. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_ingest_accounting.py +0 -0
  399. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_ingest_freshness.py +0 -0
  400. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_ingest_helicone.py +0 -0
  401. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_ingest_otlp.py +0 -0
  402. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_ingested_ids_endpoint.py +0 -0
  403. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_lens_dashboard_states.py +0 -0
  404. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_lens_module_parses.py +0 -0
  405. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_lens_optimize_switch_states.py +0 -0
  406. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_lens_persona_hidden_mirror.py +0 -0
  407. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_lens_select_all_behaviour.py +0 -0
  408. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_lens_sessions_zone_spacing.py +0 -0
  409. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_lens_ui_regression.py +0 -0
  410. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_litellm_client.py +0 -0
  411. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_litellm_integration.py +0 -0
  412. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_logs_converter.py +0 -0
  413. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_loop.py +0 -0
  414. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_loop_api.py +0 -0
  415. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_loop_transcript_path.py +0 -0
  416. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_main_lock_holder_hint.py +0 -0
  417. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_mcp_policy.py +0 -0
  418. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_mcp_probe.py +0 -0
  419. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_mcp_readonly_schema_gap.py +0 -0
  420. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_mcp_server.py +0 -0
  421. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_mcp_setup_project_tj_config.py +0 -0
  422. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_method_capture.py +0 -0
  423. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_method_spine.py +0 -0
  424. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_model_apply.py +0 -0
  425. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_model_tiers.py +0 -0
  426. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_models.py +0 -0
  427. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_mythos_premium_gates.py +0 -0
  428. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_no_fix_prose_outside_the_catalog.py +0 -0
  429. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_no_sentinel_timestamps.py +0 -0
  430. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_no_tracked_dev_secrets.py +0 -0
  431. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_no_tracker_ids_in_printed_strings.py +0 -0
  432. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_onboard_add_project.py +0 -0
  433. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_onboard_backfill_scope.py +0 -0
  434. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_onboard_budget_gate.py +0 -0
  435. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_onboard_capture_default.py +0 -0
  436. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_onboard_codex.py +0 -0
  437. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_onboard_daemon.py +0 -0
  438. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_onboard_detect.py +0 -0
  439. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_onboard_ephemeral_guard.py +0 -0
  440. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_onboard_first_run.py +0 -0
  441. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_onboard_hygiene.py +0 -0
  442. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_onboard_path_branch.py +0 -0
  443. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_onboard_path_resolution.py +0 -0
  444. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_onboard_plan.py +0 -0
  445. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_onboard_project_flag_removed.py +0 -0
  446. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_onboard_resume_hook.py +0 -0
  447. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_onboard_stack_detection.py +0 -0
  448. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_onboard_statusline.py +0 -0
  449. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_onboard_tool_inputs_default.py +0 -0
  450. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_onboard_verify.py +0 -0
  451. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_onboard_verify_cli.py +0 -0
  452. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_onboard_zshrc_otel.py +0 -0
  453. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_openclaw_ingest.py +0 -0
  454. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_optimize.py +0 -0
  455. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_optimize_analyzers_route.py +0 -0
  456. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_optimize_clustering.py +0 -0
  457. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_optimize_plan_multiplier.py +0 -0
  458. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_optimize_rank.py +0 -0
  459. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_optimize_recoverable.py +0 -0
  460. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_optimize_resend_render.py +0 -0
  461. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_optimize_reuse.py +0 -0
  462. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_optimize_savings_ci.py +0 -0
  463. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_optimize_scoreboard.py +0 -0
  464. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_optimize_subagent.py +0 -0
  465. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_optimize_summarize.py +0 -0
  466. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_optimize_threshold_rendering.py +0 -0
  467. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_optimize_trim_provenance.py +0 -0
  468. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_optimize_validate.py +0 -0
  469. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_opus_quota_audit.py +0 -0
  470. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_past_overspend.py +0 -0
  471. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_persona_analyzer_gate.py +0 -0
  472. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_persona_population_scope.py +0 -0
  473. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_persona_scoped_endpoints.py +0 -0
  474. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_phases.py +0 -0
  475. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_ping.py +0 -0
  476. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_plan_tier_apply.py +0 -0
  477. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_plugin_command_docs_namespaced.py +0 -0
  478. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_policy_engine.py +0 -0
  479. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_pricing_coverage.py +0 -0
  480. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_pricing_lookup_forms.py +0 -0
  481. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_pricing_override.py +0 -0
  482. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_prompt_bloat.py +0 -0
  483. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_provider_attribution_194.py +0 -0
  484. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_provider_content_capture.py +0 -0
  485. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_provider_run_id.py +0 -0
  486. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_proxy_audit.py +0 -0
  487. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_proxy_gate.py +0 -0
  488. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_rate_profile.py +0 -0
  489. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_recommendations.py +0 -0
  490. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_relearn.py +0 -0
  491. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_relearn_apply.py +0 -0
  492. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_relearn_archive_and_cost.py +0 -0
  493. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_relearn_cli.py +0 -0
  494. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_relearn_families_and_boundary.py +0 -0
  495. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_relearn_otel.py +0 -0
  496. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_relearn_window.py +0 -0
  497. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_repeat_task.py +0 -0
  498. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_repo_context.py +0 -0
  499. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_report_roundtrip.py +0 -0
  500. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_report_window.py +0 -0
  501. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_reset.py +0 -0
  502. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_resume_brief.py +0 -0
  503. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_reuse_skeleton.py +0 -0
  504. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_rollup_covers_every_rendered_row.py +0 -0
  505. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_rollup_subagent_downsize_dedup.py +0 -0
  506. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_rule_placement.py +0 -0
  507. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_rule_presence.py +0 -0
  508. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_rulewrite_applied_detection.py +0 -0
  509. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_rulewrite_dismissal.py +0 -0
  510. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_rulewrite_legacy.py +0 -0
  511. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_rulewrite_lifecycle.py +0 -0
  512. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_runlink.py +0 -0
  513. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_scan_bar_truth.py +0 -0
  514. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_scan_cycle_provenance.py +0 -0
  515. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_scan_watermark.py +0 -0
  516. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_sdk_agent_session.py +0 -0
  517. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_sdk_attribution.py +0 -0
  518. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_serve_transcript_catchup.py +0 -0
  519. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_server_state.py +0 -0
  520. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_session_commits.py +0 -0
  521. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_session_cost_drift.py +0 -0
  522. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_session_label.py +0 -0
  523. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_session_provenance.py +0 -0
  524. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_session_repo_context.py +0 -0
  525. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_session_status_lifecycle.py +0 -0
  526. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_session_subagents.py +0 -0
  527. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_sessionmap.py +0 -0
  528. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_single_derivation.py +0 -0
  529. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_span_pricing.py +0 -0
  530. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_spans_stats_repair.py +0 -0
  531. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_status_overview.py +0 -0
  532. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_status_sdk.py +0 -0
  533. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_statusline.py +0 -0
  534. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_statusline_driver_staleness.py +0 -0
  535. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_stream_usage_analyzer.py +0 -0
  536. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_stream_usage_capture.py +0 -0
  537. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_subagent_rubric_contradiction.py +0 -0
  538. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_summarize_apply.py +0 -0
  539. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_summarize_backup.py +0 -0
  540. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_summarize_calibrate.py +0 -0
  541. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_summarize_candidates.py +0 -0
  542. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_summarize_catalog.py +0 -0
  543. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_summarize_classify.py +0 -0
  544. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_summarize_delivery.py +0 -0
  545. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_summarize_detect.py +0 -0
  546. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_summarize_estimate.py +0 -0
  547. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_summarize_invocations.py +0 -0
  548. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_summarize_load_semantics.py +0 -0
  549. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_summarize_numbering.py +0 -0
  550. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_summarize_prompt_fence.py +0 -0
  551. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_summarize_prune_quarantine.py +0 -0
  552. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_summarize_relocate.py +0 -0
  553. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_summarize_repo_roots.py +0 -0
  554. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_summarize_route.py +0 -0
  555. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_summarize_sections.py +0 -0
  556. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_summarize_session.py +0 -0
  557. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_summarize_wrap.py +0 -0
  558. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_time_parse.py +0 -0
  559. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_tj_db_guard.py +0 -0
  560. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_transcript.py +0 -0
  561. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_transcript_cache.py +0 -0
  562. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_transcript_refill.py +0 -0
  563. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_transcript_sync.py +0 -0
  564. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_transport_401.py +0 -0
  565. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_ui_offline.py +0 -0
  566. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_uninstall_persistent_install.py +0 -0
  567. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_uninstall_runner_detect.py +0 -0
  568. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_uninstall_wrapper.py +0 -0
  569. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_usage.py +0 -0
  570. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_workflow_restructure.py +0 -0
  571. {tokenjam-0.7.0 → tokenjam-0.7.1}/tests/unit/test_workmap.py +0 -0
  572. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/__init__.py +0 -0
  573. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/api/__init__.py +0 -0
  574. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/api/deps.py +0 -0
  575. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/api/middleware.py +0 -0
  576. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/api/routes/__init__.py +0 -0
  577. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/api/routes/_body.py +0 -0
  578. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/api/routes/agents.py +0 -0
  579. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/api/routes/alerts.py +0 -0
  580. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/api/routes/analytics.py +0 -0
  581. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/api/routes/backfill.py +0 -0
  582. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/api/routes/budget.py +0 -0
  583. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/api/routes/context.py +0 -0
  584. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/api/routes/cost_compare.py +0 -0
  585. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/api/routes/drift.py +0 -0
  586. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/api/routes/logs.py +0 -0
  587. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/api/routes/loop.py +0 -0
  588. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/api/routes/metrics.py +0 -0
  589. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/api/routes/optimize.py +0 -0
  590. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/api/routes/otlp.py +0 -0
  591. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/api/routes/persona.py +0 -0
  592. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/api/routes/policy.py +0 -0
  593. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/api/routes/quota_audit.py +0 -0
  594. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/api/routes/recommendations.py +0 -0
  595. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/api/routes/relearn.py +0 -0
  596. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/api/routes/reuse.py +0 -0
  597. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/api/routes/rules.py +0 -0
  598. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/api/routes/runs.py +0 -0
  599. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/api/routes/shipped.py +0 -0
  600. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/api/routes/spans.py +0 -0
  601. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/api/routes/summarize.py +0 -0
  602. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/api/routes/summarize_run.py +0 -0
  603. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/api/routes/tools.py +0 -0
  604. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/api/routes/version.py +0 -0
  605. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/cli/__init__.py +0 -0
  606. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/cli/backfill_progress.py +0 -0
  607. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/cli/banner.py +0 -0
  608. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/cli/cmd_alerts.py +0 -0
  609. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/cli/cmd_budget.py +0 -0
  610. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/cli/cmd_commit_note.py +0 -0
  611. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/cli/cmd_context.py +0 -0
  612. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/cli/cmd_demo.py +0 -0
  613. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/cli/cmd_drift.py +0 -0
  614. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/cli/cmd_export.py +0 -0
  615. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/cli/cmd_loop.py +0 -0
  616. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/cli/cmd_mcp.py +0 -0
  617. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/cli/cmd_onboard.py +0 -0
  618. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/cli/cmd_otel.py +0 -0
  619. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/cli/cmd_ping.py +0 -0
  620. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/cli/cmd_pricing.py +0 -0
  621. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/cli/cmd_proxy.py +0 -0
  622. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/cli/cmd_quickstart.py +0 -0
  623. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/cli/cmd_quota_audit.py +0 -0
  624. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/cli/cmd_relearn.py +0 -0
  625. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/cli/cmd_report.py +0 -0
  626. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/cli/cmd_reset.py +0 -0
  627. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/cli/cmd_resume_brief.py +0 -0
  628. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/cli/cmd_route.py +0 -0
  629. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/cli/cmd_rules.py +0 -0
  630. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/cli/cmd_serve.py +0 -0
  631. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/cli/cmd_session_end.py +0 -0
  632. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/cli/cmd_session_story.py +0 -0
  633. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/cli/cmd_statusline.py +0 -0
  634. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/cli/cmd_stop.py +0 -0
  635. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/cli/cmd_summarize.py +0 -0
  636. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/cli/cmd_tokenmaxx.py +0 -0
  637. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/cli/cmd_tools.py +0 -0
  638. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/cli/cmd_traces.py +0 -0
  639. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/cli/cmd_uninstall.py +0 -0
  640. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/cli/cmd_upgrade.py +0 -0
  641. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/cli/cost_proposal_verbs.py +0 -0
  642. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/cli/data_access.py +0 -0
  643. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/cli/entrypoint.py +0 -0
  644. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/cli/home.py +0 -0
  645. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/cli/json_option.py +0 -0
  646. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/cli/ledger_cloud.py +0 -0
  647. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/cli/ledger_hooks.py +0 -0
  648. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/cli/main.py +0 -0
  649. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/cli/onboard_detect.py +0 -0
  650. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/cli/relearn_write_verbs.py +0 -0
  651. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/cli/tj_status.py +0 -0
  652. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/__init__.py +0 -0
  653. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/agent_config.py +0 -0
  654. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/agent_kind.py +0 -0
  655. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/analysis_span.py +0 -0
  656. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/atomic_write.py +0 -0
  657. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/attribution_cache.py +0 -0
  658. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/backfill.py +0 -0
  659. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/cloud_sync.py +0 -0
  660. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/commit_hooks.py +0 -0
  661. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/cycle.py +0 -0
  662. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/data_span.py +0 -0
  663. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/distill.py +0 -0
  664. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/drift.py +0 -0
  665. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/export/__init__.py +0 -0
  666. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/export/ccr.py +0 -0
  667. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/export/claude_code.py +0 -0
  668. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/export/common.py +0 -0
  669. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/export/litellm.py +0 -0
  670. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/export/reuse_report.py +0 -0
  671. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/export/reuse_skeleton.py +0 -0
  672. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/fixes/__init__.py +0 -0
  673. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/fixes/catalog.py +0 -0
  674. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/fixes/grounding.py +0 -0
  675. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/fixes/lint.py +0 -0
  676. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/fixes/registry.py +0 -0
  677. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/harness_setup.py +0 -0
  678. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/ingest_adapters/__init__.py +0 -0
  679. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/ingest_adapters/codex.py +0 -0
  680. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/ingest_adapters/helicone.py +0 -0
  681. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/ingest_adapters/otlp.py +0 -0
  682. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/ingest_freshness.py +0 -0
  683. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/loop.py +0 -0
  684. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/method_capture.py +0 -0
  685. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/method_spine.py +0 -0
  686. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/model_tiers.py +0 -0
  687. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/onboard_verify.py +0 -0
  688. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/optimize/README.md +0 -0
  689. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/optimize/__init__.py +0 -0
  690. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/optimize/accounting.py +0 -0
  691. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/optimize/analyzers/__init__.py +0 -0
  692. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/optimize/analyzers/batch_placement.py +0 -0
  693. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/optimize/analyzers/budget_projection.py +0 -0
  694. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/optimize/analyzers/cache_efficacy.py +0 -0
  695. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/optimize/analyzers/cache_recommend.py +0 -0
  696. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/optimize/analyzers/context_resend.py +0 -0
  697. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/optimize/analyzers/deadweight.py +0 -0
  698. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/optimize/analyzers/downsize_agents.py +0 -0
  699. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/optimize/analyzers/model_downgrade.py +0 -0
  700. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/optimize/analyzers/output_verbosity.py +0 -0
  701. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/optimize/analyzers/plan_reuse.py +0 -0
  702. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/optimize/analyzers/prompt_bloat.py +0 -0
  703. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/optimize/analyzers/relearn.py +0 -0
  704. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/optimize/analyzers/resend_tail.py +0 -0
  705. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/optimize/analyzers/shipped.py +0 -0
  706. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/optimize/analyzers/stream_usage.py +0 -0
  707. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/optimize/analyzers/subagent_rightsizing.py +0 -0
  708. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/optimize/analyzers/summarize.py +0 -0
  709. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/optimize/analyzers/workflow_restructure.py +0 -0
  710. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/optimize/clustering.py +0 -0
  711. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/optimize/cost_apply.py +0 -0
  712. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/optimize/cost_proposals.py +0 -0
  713. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/optimize/cycle_provenance.py +0 -0
  714. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/optimize/dismissals.py +0 -0
  715. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/optimize/inbox_contribution.py +0 -0
  716. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/optimize/ingest_watermark.py +0 -0
  717. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/optimize/mcp_probe.py +0 -0
  718. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/optimize/model_apply.py +0 -0
  719. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/optimize/projection.py +0 -0
  720. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/optimize/rank.py +0 -0
  721. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/optimize/rate_profile.py +0 -0
  722. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/optimize/registry.py +0 -0
  723. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/optimize/relearn_apply.py +0 -0
  724. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/optimize/relearn_otel.py +0 -0
  725. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/optimize/relearn_proposals.py +0 -0
  726. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/optimize/relearn_store.py +0 -0
  727. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/optimize/relearn_window.py +0 -0
  728. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/optimize/repeat_task.py +0 -0
  729. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/optimize/report_store.py +0 -0
  730. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/optimize/report_window.py +0 -0
  731. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/optimize/rule_placement.py +0 -0
  732. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/optimize/rule_scope.py +0 -0
  733. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/optimize/runner.py +0 -0
  734. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/optimize/scan_cycle.py +0 -0
  735. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/optimize/scope.py +0 -0
  736. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/optimize/single_derivation.py +0 -0
  737. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/optimize/span_pricing.py +0 -0
  738. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/optimize/stats.py +0 -0
  739. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/optimize/types.py +0 -0
  740. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/optimize/validate.py +0 -0
  741. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/persona_scope.py +0 -0
  742. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/phases.py +0 -0
  743. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/pricing.py +0 -0
  744. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/pricing_coverage.py +0 -0
  745. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/recommendations.py +0 -0
  746. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/repo_context.py +0 -0
  747. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/resume_brief.py +0 -0
  748. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/retention.py +0 -0
  749. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/rulewrite/__init__.py +0 -0
  750. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/rulewrite/apply.py +0 -0
  751. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/rulewrite/delivery.py +0 -0
  752. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/rulewrite/kinds.py +0 -0
  753. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/rulewrite/legacy.py +0 -0
  754. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/rulewrite/plan.py +0 -0
  755. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/rulewrite/presence.py +0 -0
  756. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/rulewrite/store.py +0 -0
  757. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/rulewrite/types.py +0 -0
  758. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/runlink.py +0 -0
  759. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/savings_log.py +0 -0
  760. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/schema_validator.py +0 -0
  761. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/server_state.py +0 -0
  762. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/sessionmap.py +0 -0
  763. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/shipped.py +0 -0
  764. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/summarize/__init__.py +0 -0
  765. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/summarize/agent_files.toml +0 -0
  766. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/summarize/apply.py +0 -0
  767. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/summarize/backup.py +0 -0
  768. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/summarize/calibrate.py +0 -0
  769. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/summarize/candidates.py +0 -0
  770. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/summarize/catalog.py +0 -0
  771. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/summarize/classify.py +0 -0
  772. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/summarize/delivery.py +0 -0
  773. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/summarize/detect.py +0 -0
  774. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/summarize/estimate.py +0 -0
  775. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/summarize/invocations.py +0 -0
  776. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/summarize/load_semantics.py +0 -0
  777. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/summarize/numbering.py +0 -0
  778. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/summarize/prune.py +0 -0
  779. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/summarize/quarantine.py +0 -0
  780. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/summarize/relocate.py +0 -0
  781. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/summarize/repo_roots.py +0 -0
  782. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/summarize/route.py +0 -0
  783. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/summarize/sections.py +0 -0
  784. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/summarize/session.py +0 -0
  785. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/summarize/wrap.py +0 -0
  786. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/system_prefix.py +0 -0
  787. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/transcript.py +0 -0
  788. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/transcript_cache.py +0 -0
  789. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/transcript_sync.py +0 -0
  790. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/usage.py +0 -0
  791. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/core/workmap.py +0 -0
  792. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/demo/__init__.py +0 -0
  793. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/demo/env.py +0 -0
  794. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/demo/live.py +0 -0
  795. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/hooks/post-commit +0 -0
  796. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/hooks/prepare-commit-msg +0 -0
  797. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/mcp/__init__.py +0 -0
  798. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/mcp/server.py +0 -0
  799. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/otel/__init__.py +0 -0
  800. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/otel/otlp_parsing.py +0 -0
  801. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/otel/semconv.py +0 -0
  802. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/proxy/__init__.py +0 -0
  803. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/proxy/app.py +0 -0
  804. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/proxy/audit.py +0 -0
  805. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/proxy/engine.py +0 -0
  806. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/proxy/gate.py +0 -0
  807. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/proxy/observer.py +0 -0
  808. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/proxy/recommend.py +0 -0
  809. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/proxy/server.py +0 -0
  810. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/proxy/stream_usage.py +0 -0
  811. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/proxy/wiring.py +0 -0
  812. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/py.typed +0 -0
  813. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/sdk/__init__.py +0 -0
  814. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/sdk/agent.py +0 -0
  815. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/sdk/attribution.py +0 -0
  816. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/sdk/client.py +0 -0
  817. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/sdk/integrations/__init__.py +0 -0
  818. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/sdk/integrations/_request_capture.py +0 -0
  819. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/sdk/integrations/anthropic.py +0 -0
  820. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/sdk/integrations/autogen.py +0 -0
  821. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/sdk/integrations/base.py +0 -0
  822. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/sdk/integrations/bedrock.py +0 -0
  823. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/sdk/integrations/crewai.py +0 -0
  824. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/sdk/integrations/gemini.py +0 -0
  825. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/sdk/integrations/langchain.py +0 -0
  826. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/sdk/integrations/langgraph.py +0 -0
  827. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/sdk/integrations/litellm.py +0 -0
  828. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/sdk/integrations/llamaindex.py +0 -0
  829. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/sdk/integrations/nemoclaw.py +0 -0
  830. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/sdk/integrations/openai.py +0 -0
  831. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/sdk/integrations/openai_agents_sdk.py +0 -0
  832. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/sdk/transport.py +0 -0
  833. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/ui/vendor/fonts/Geist-Variable.woff2 +0 -0
  834. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/ui/vendor/fonts/GeistMono-Variable.woff2 +0 -0
  835. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/ui/vendor/fonts/LICENSE-Geist.txt +0 -0
  836. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/ui/vendor/htm.js +0 -0
  837. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/ui/vendor/preact-hooks.js +0 -0
  838. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/ui/vendor/preact.js +0 -0
  839. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/ui/vendor/uplot.css +0 -0
  840. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/ui/vendor/uplot.js +0 -0
  841. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/utils/__init__.py +0 -0
  842. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/utils/formatting.py +0 -0
  843. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/utils/humanize.py +0 -0
  844. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/utils/ids.py +0 -0
  845. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/utils/signatures.py +0 -0
  846. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/utils/theme.py +0 -0
  847. {tokenjam-0.7.0 → tokenjam-0.7.1}/tokenjam/utils/time_parse.py +0 -0
@@ -74,7 +74,7 @@ joins the session of any sibling span on the same `trace_id`.
74
74
 
75
75
  **Rule: both cache fields belong on both sides of every token sum and every price comparison** — an omission that recurs in `core/optimize/`. **(a) In aggregates**, sum cache reads AND cache writes in the same expression; `COALESCE(SUM(input_tokens + output_tokens + cache_tokens + cache_write_tokens), 0)` (the form in `optimize/runner.py`) is canonical for per-cluster and per-session totals — grep `SUM.*cache_tokens` when adding one. **(b) In pricing comparisons**, an actual-vs-alternative-model savings figure must price cache identically on both sides: a hand-rolled alt-price helper omitting cache-write while the actual `cost_usd` bills it inflates every derived saving by the candidate's full cache-write cost, and evades that grep because the SQL is correct and the Python pricing is not — the omission lives in a per-row helper, not a `SUM`. **Keep exactly one pricer:** route every alternative-side computation through `calculate_cost`, which covers all four token classes.
76
76
 
77
- - **`alerts.py`** — `AlertEngine` (the kinds it can fire are the `AlertType` enum in `core/models.py`; read the enum, never a count kept here), `CooldownTracker` (in-memory, per agent+type, resets on restart), `AlertDispatcher` routing to the channel types the `_build_channel` factory knows (stdout, file, ntfy, webhook, Discord, Telegram — that factory is the live set). `AlertEngine.fire()` is the entry point for `SchemaValidator` and `DriftDetector`. Suppressed alerts are still persisted, just not dispatched. Thresholds are module-level constants, not config — read them for values: **retry loop** fires when the same tool call repeats often enough inside a trailing span window (`_RETRY_LOOP_THRESHOLD` / `_RETRY_LOOP_WINDOW`); **failure rate** when the error share over a trailing span window crosses a ceiling, re-evaluated only every Nth error to bound cost (`_FAILURE_RATE_THRESHOLD` / `_FAILURE_RATE_WINDOW` / `_FAILURE_RATE_CHECK_INTERVAL`); **session duration** past a default wall-clock ceiling (`_SESSION_DURATION_DEFAULT`). Stdout and file channels always include full detail regardless of `include_captured_content`.
77
+ - **`alerts.py`** — `AlertEngine` (the kinds it can fire are the `AlertType` enum in `core/models.py`; read the enum, never a count kept here), `CooldownTracker` (in-memory, per agent+type, resets on restart), `AlertDispatcher` routing to the channel types the `_build_channel` factory knows (stdout, file, ntfy, webhook, Discord, Telegram, Mast — that factory is the live set). `AlertEngine.fire()` is the entry point for `SchemaValidator` and `DriftDetector`. Suppressed alerts are still persisted, just not dispatched. Thresholds are module-level constants, not config — read them for values: **retry loop** fires when the same tool call repeats often enough inside a trailing span window (`_RETRY_LOOP_THRESHOLD` / `_RETRY_LOOP_WINDOW`); **failure rate** when the error share over a trailing span window crosses a ceiling, re-evaluated only every Nth error to bound cost (`_FAILURE_RATE_THRESHOLD` / `_FAILURE_RATE_WINDOW` / `_FAILURE_RATE_CHECK_INTERVAL`); **session duration** past a default wall-clock ceiling (`_SESSION_DURATION_DEFAULT`). Stdout and file channels always include full detail regardless of `include_captured_content`.
78
78
 
79
79
  - **`drift.py`** — `DriftDetector`, Z-score based behavioral drift detection, fires at session end.
80
80
 
@@ -28,8 +28,11 @@ the sidebar wordmark, and the OpenAPI title, but never in module names, route pa
28
28
  Screens: **Overview** (the default landing route — a triage front door), Status, Traces, Cost,
29
29
  Alerts, Drift, Optimize (with **Summarize** and **Rules** sub-views), Budget.
30
30
 
31
- `app.py` reads `index.html` into a module string once at `create_app()` time, so editing it requires
32
- a `tj serve` restart to take effect; tests read the file from disk directly and aren't affected.
31
+ `app.py` caches `index.html` in memory but re-reads it whenever the file's mtime changes (one `stat()` per
32
+ request), so edits show up on the next page reload against a running `tj serve` — no restart needed. The
33
+ `tj-api-key` / `tj-write-token` `<meta>` injection runs on every response, so it applies to the re-read HTML
34
+ too. Changes to `ui/vendor/*` are plain `StaticFiles` and were never cached by the app. Tests read the file
35
+ from disk directly and aren't affected.
33
36
 
34
37
  - **Offline-first (Critical Rule 18, `.claude/rules/web-ui.md`):** every JS/CSS dep is vendored under `vendor/` — Preact + hooks + htm (ESM via `<script type="importmap">`) and **uPlot** (vendored IIFE global `uPlot` + CSS, pinned in `docs/internal/lens-vendor-versions.md`). No render-time external HTTP. `tests/unit/test_ui_offline.py` enforces this; clickable `<a href>` links are the only allowed external URLs.
35
38
  - **Single compute path:** the UI reads everything from the REST API and **never re-implements analysis, aggregation, or plan-tier framing in JS** — it consumes the `framing` block (see `core/framing.py`). If the UI needs a number, extend the endpoint; don't compute it client-side. This applies to gating/filter sets too, not just numbers: if a Python-side map decides which analyzers/findings apply to a persona (e.g. `core/optimize/runner.py`'s `PERSONA_DISABLED_ANALYZERS`), the API already publishes the resolved set (`persona_disabled_analyzers` on `/optimize`) — read that field everywhere the gate is needed, never re-declare the map as a second JS literal. Two call sites deriving the same set from two different sources will silently desync the moment either side edits its copy.
@@ -14,8 +14,12 @@ automatically by GitHub Actions). The default workflow token works because the
14
14
  workflow grants `administration: read`, which the Traffic API requires.
15
15
 
16
16
  Failure mode: any API error raises and the process exits non-zero, so the run
17
- shows red in the Actions tab (the Cowork health check then alerts on the missing
18
- file). No-data weeks still write the file — its existence is the success signal.
17
+ shows red in the Actions tab. **Nothing else watches it** — the health check that
18
+ this docstring used to promise was descoped before the workflow shipped (see
19
+ growth/README.md), and that gap is why a broken publish step went unnoticed from
20
+ 2026-W26 to 2026-W41 while this script kept succeeding every week. If you are
21
+ relying on this archive, check the branch rather than assuming a green pipeline.
22
+ No-data weeks still write the file — its existence is the success signal.
19
23
  """
20
24
  from __future__ import annotations
21
25
 
@@ -56,15 +56,60 @@ jobs:
56
56
  GH_REPO: ${{ github.repository }}
57
57
  WEEK: ${{ steps.archive.outputs.iso_week }}
58
58
  run: |
59
+ set -euo pipefail
60
+ remote="https://x-access-token:${GH_TOKEN}@github.com/${GH_REPO}.git"
59
61
  tmp="$(mktemp -d)"
60
- git clone --quiet --depth 1 --branch traffic-data \
61
- "https://x-access-token:${GH_TOKEN}@github.com/${GH_REPO}.git" "$tmp"
62
+
63
+ # Create traffic-data if it is missing rather than dying on it. The
64
+ # branch disappeared once (deleted, or never recreated after a repo
65
+ # operation) and every weekly run from 2026-W26 to 2026-W41 then
66
+ # failed on `fatal: Remote branch traffic-data not found`, AFTER the
67
+ # collect step had succeeded. Fifteen weeks of snapshots were
68
+ # gathered and thrown away; the Traffic API retains only 14 days, so
69
+ # every week before the current window is gone for good. A missing
70
+ # branch is a recoverable state, so recover from it: the archive's
71
+ # whole purpose is to outlive that 14-day window, and a publisher
72
+ # that cannot create its own destination defeats it on the one day
73
+ # it matters.
74
+ #
75
+ # Distinguish "no such branch" from "could not ask". `ls-remote
76
+ # --exit-code` returns 2 for no matching ref and 128 for a transport
77
+ # or auth failure, so swallowing every non-zero status would let a
78
+ # momentary network blip start a fresh local history against a branch
79
+ # that already exists -- the push then fails as a non-fast-forward,
80
+ # and the run looks like the very bug this step fixes. Only 2 means
81
+ # create; anything else re-raises with git's own message.
82
+ set +e
83
+ git ls-remote --exit-code --heads "$remote" traffic-data >/dev/null
84
+ ls_status=$?
85
+ set -e
86
+ if [ "$ls_status" -eq 0 ]; then
87
+ git clone --quiet --depth 1 --branch traffic-data "$remote" "$tmp"
88
+ elif [ "$ls_status" -ne 2 ]; then
89
+ echo "error: could not reach ${GH_REPO} to check for traffic-data" \
90
+ "(git ls-remote exit ${ls_status}). Refusing to guess that the" \
91
+ "branch is missing." >&2
92
+ git ls-remote --heads "$remote" traffic-data >/dev/null
93
+ exit "$ls_status"
94
+ else
95
+ echo "traffic-data does not exist on ${GH_REPO} — creating it."
96
+ git -C "$tmp" init --quiet --initial-branch=traffic-data
97
+ git -C "$tmp" remote add origin "$remote"
98
+ printf '%s\n' \
99
+ '# traffic-data' '' \
100
+ 'Data-only orphan branch. Weekly GitHub Traffic API snapshots live under' \
101
+ '`traffic/<ISO-year>-W<week>.json`, written by .github/workflows/traffic-archive.yml' \
102
+ 'on main. Nothing here is source; do not merge this branch into main.' \
103
+ > "$tmp/README.md"
104
+ git -C "$tmp" add README.md
105
+ fi
106
+
62
107
  mkdir -p "$tmp/traffic"
63
108
  cp "traffic/${WEEK}.json" "$tmp/traffic/${WEEK}.json"
64
109
  git -C "$tmp" config user.name "github-actions[bot]"
65
110
  git -C "$tmp" config user.email "41898282+github-actions[bot]@users.noreply.github.com"
66
111
  git -C "$tmp" add traffic/
67
- if git -C "$tmp" diff --cached --quiet; then
112
+ if git -C "$tmp" diff --cached --quiet && git -C "$tmp" rev-parse HEAD >/dev/null 2>&1; then
68
113
  echo "No changes — archive already current for ${WEEK}."
69
114
  exit 0
70
115
  fi
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: tokenjam
3
- Version: 0.7.0
3
+ Version: 0.7.1
4
4
  Summary: TokenJam: a local-first, OTel-native cost-saving utility for AI agents
5
5
  Project-URL: Homepage, https://tokenjam.dev
6
6
  Project-URL: Repository, https://github.com/Metabuilder-Labs/tokenjam
@@ -94,7 +94,7 @@ One command sets up live capture:
94
94
  npx tokenjam onboard # or: pipx install tokenjam && tj onboard
95
95
  ```
96
96
 
97
- `tj onboard` asks how you use AI agents and wires that path: live capture, the analyzers your setup can act on, and Lens. Coding-agent users (Claude Code, Codex) also get their recent history backfilled and a zero-token status line wired in; restart the agent and you're live. SDK and API users add `@watch()` to their own code, or point an OTLP exporter at `tj serve`.
97
+ `tj init` is the same command (`tj onboard` is its original name, still there). It asks how you use AI agents and wires that path: live capture, the analyzers your setup can act on, and Lens. Coding-agent users (Claude Code, Codex) also get their recent history backfilled and a zero-token status line wired in; restart the agent and you're live. SDK and API users add `@watch()` to their own code, or point an OTLP exporter at `tj serve`.
98
98
 
99
99
  Then open the dashboard:
100
100
 
@@ -184,9 +184,12 @@ subset with `tj optimize downsize resend relearn`.
184
184
  | `verbosity` | — | ✅ | Sessions whose output runs long against a per-(tool, task-shape) baseline |
185
185
  | `script` | — | ✅ | Deterministic tool sequences a plain script could replace |
186
186
  | `reuse` | — | ✅ | Sessions where your agent re-plans work it has already planned |
187
+ | `shipped` | ✅ | ✅ | What your sessions left behind: commits joined to sessions, what the ones that shipped nothing cost, and what got rewritten |
187
188
 
188
189
  They find where your agents are overspending. They also tell you where they are not, so you don't spend a week optimizing something that was never costing you anything.
189
190
 
191
+ `shipped` is the odd one out, and deliberately so. Every other analyzer asks what a session cost; this one asks what it produced. It joins each session to the commits it made, at a labelled confidence, and reports what the sessions that shipped nothing cost. Nothing in it is a saving: it is measured spend next to measured output, and a session can ship value without a commit. `tj init --hooks` makes commits you type by hand carry a session trailer, which raises how much of your work tj can join. [How the join works →](docs/ledger/overview.md)
192
+
190
193
  That balance is why some checks stay dark for you: when the lever that would recover a category of spend belongs to your harness rather than to you, quoting the figure only makes you feel worse. A check also stays dark when its evidence does not exist on your setup; `summarize` reads agent instruction files off disk, which an SDK or API workload does not have, so it is not offered there. It is also why a quiet result is an answer rather than a failed scan. Optimizing has a price of its own, paid in your attention and sometimes in the agent's output, and a bill lowered by making your agent terser or dumber was never a saving.
191
194
 
192
195
  ---
@@ -213,6 +216,9 @@ Bench reports measured pass-rate on a suite, never "certified" or "quality prese
213
216
  | Full CLI reference, every command and flag | [docs/cli-reference.md](docs/cli-reference.md) |
214
217
  | Downsize / Cache / Script / Trim deep-dives | [docs/optimize/](docs/optimize/) |
215
218
  | Reuse analyzer deep-dive | [docs/optimize/reuse.md](docs/optimize/reuse.md) |
219
+ | The ledger: sessions joined to commits | [docs/ledger/overview.md](docs/ledger/overview.md) |
220
+ | Commit hooks and git notes (`tj init --hooks` / `--notes`) | [docs/ledger/hooks-and-notes.md](docs/ledger/hooks-and-notes.md) |
221
+ | TokenJam Cloud bridge, and what leaves your machine | [docs/ledger/cloud-bridge.md](docs/ledger/cloud-bridge.md) |
216
222
  | Prove a downsize candidate holds (TokenJam Bench) | [tokenjam-bench](https://github.com/Metabuilder-Labs/tokenjam-bench) |
217
223
  | Claude Code & Codex integration | [docs/claude-code-integration.md](docs/claude-code-integration.md) |
218
224
  | Claude Code vs. Codex vs. SDK vs. OTLP: capability matrix | [docs/agent-capability-matrix.md](docs/agent-capability-matrix.md) |
@@ -36,7 +36,7 @@ One command sets up live capture:
36
36
  npx tokenjam onboard # or: pipx install tokenjam && tj onboard
37
37
  ```
38
38
 
39
- `tj onboard` asks how you use AI agents and wires that path: live capture, the analyzers your setup can act on, and Lens. Coding-agent users (Claude Code, Codex) also get their recent history backfilled and a zero-token status line wired in; restart the agent and you're live. SDK and API users add `@watch()` to their own code, or point an OTLP exporter at `tj serve`.
39
+ `tj init` is the same command (`tj onboard` is its original name, still there). It asks how you use AI agents and wires that path: live capture, the analyzers your setup can act on, and Lens. Coding-agent users (Claude Code, Codex) also get their recent history backfilled and a zero-token status line wired in; restart the agent and you're live. SDK and API users add `@watch()` to their own code, or point an OTLP exporter at `tj serve`.
40
40
 
41
41
  Then open the dashboard:
42
42
 
@@ -126,9 +126,12 @@ subset with `tj optimize downsize resend relearn`.
126
126
  | `verbosity` | — | ✅ | Sessions whose output runs long against a per-(tool, task-shape) baseline |
127
127
  | `script` | — | ✅ | Deterministic tool sequences a plain script could replace |
128
128
  | `reuse` | — | ✅ | Sessions where your agent re-plans work it has already planned |
129
+ | `shipped` | ✅ | ✅ | What your sessions left behind: commits joined to sessions, what the ones that shipped nothing cost, and what got rewritten |
129
130
 
130
131
  They find where your agents are overspending. They also tell you where they are not, so you don't spend a week optimizing something that was never costing you anything.
131
132
 
133
+ `shipped` is the odd one out, and deliberately so. Every other analyzer asks what a session cost; this one asks what it produced. It joins each session to the commits it made, at a labelled confidence, and reports what the sessions that shipped nothing cost. Nothing in it is a saving: it is measured spend next to measured output, and a session can ship value without a commit. `tj init --hooks` makes commits you type by hand carry a session trailer, which raises how much of your work tj can join. [How the join works →](docs/ledger/overview.md)
134
+
132
135
  That balance is why some checks stay dark for you: when the lever that would recover a category of spend belongs to your harness rather than to you, quoting the figure only makes you feel worse. A check also stays dark when its evidence does not exist on your setup; `summarize` reads agent instruction files off disk, which an SDK or API workload does not have, so it is not offered there. It is also why a quiet result is an answer rather than a failed scan. Optimizing has a price of its own, paid in your attention and sometimes in the agent's output, and a bill lowered by making your agent terser or dumber was never a saving.
133
136
 
134
137
  ---
@@ -155,6 +158,9 @@ Bench reports measured pass-rate on a suite, never "certified" or "quality prese
155
158
  | Full CLI reference, every command and flag | [docs/cli-reference.md](docs/cli-reference.md) |
156
159
  | Downsize / Cache / Script / Trim deep-dives | [docs/optimize/](docs/optimize/) |
157
160
  | Reuse analyzer deep-dive | [docs/optimize/reuse.md](docs/optimize/reuse.md) |
161
+ | The ledger: sessions joined to commits | [docs/ledger/overview.md](docs/ledger/overview.md) |
162
+ | Commit hooks and git notes (`tj init --hooks` / `--notes`) | [docs/ledger/hooks-and-notes.md](docs/ledger/hooks-and-notes.md) |
163
+ | TokenJam Cloud bridge, and what leaves your machine | [docs/ledger/cloud-bridge.md](docs/ledger/cloud-bridge.md) |
158
164
  | Prove a downsize candidate holds (TokenJam Bench) | [tokenjam-bench](https://github.com/Metabuilder-Labs/tokenjam-bench) |
159
165
  | Claude Code & Codex integration | [docs/claude-code-integration.md](docs/claude-code-integration.md) |
160
166
  | Claude Code vs. Codex vs. SDK vs. OTLP: capability matrix | [docs/agent-capability-matrix.md](docs/agent-capability-matrix.md) |
@@ -0,0 +1,113 @@
1
+ # TokenJam 0.7.0
2
+
3
+ > Working draft for the GitHub release. Not part of the shipped package.
4
+
5
+ The largest release since 0.6. TokenJam has always been able to tell you what your agent sessions
6
+ cost. This one starts answering the other half of the question: what those sessions actually
7
+ produced.
8
+
9
+ ```bash
10
+ pipx install --upgrade tokenjam
11
+ tj optimize shipped
12
+ ```
13
+
14
+ ## The shipped-value ledger
15
+
16
+ tj now records which repo a session ran in and who ran it, then joins each session to the commits
17
+ it produced.
18
+
19
+ - **Repo context and developer identity on every session.** Remote, repo root, branch and HEAD at
20
+ session start and end, the git author email, and a hashed `developer_id` derived from it. Git
21
+ shell-outs are read-only, time-bounded, and never on a request path. A value that cannot be
22
+ resolved is absent rather than guessed, so nothing joins on an invented key.
23
+ - **The session-to-commit join.** A new `session_commits` table, populated on the daemon's
24
+ background pass. Four match sources: a `git commit` tool call inside the session (`tool_span_git_log`),
25
+ a `TokenJam-Session:` or `Claude-Session:` trailer (`trailer_session`), a git note naming a
26
+ session (`git_note`), and an AI co-author trailer inside the session window (`trailer_window`).
27
+ The first three are `deterministic`; the last is `inferred`. A row is written once at the best
28
+ confidence found and never downgraded.
29
+ - **The `shipped` analyzer.** `tj optimize shipped` reports how many of the window's sessions
30
+ shipped a commit to the default branch, the measured cost of the ones that shipped nothing,
31
+ rework cost (commits whose added lines were mostly deleted again within 14 days), and loop cost
32
+ (repeated Edit/Write calls on one path with no content change). Sessions also carry a state:
33
+ shipped, committed, reverted, unshipped, or no repo.
34
+ - **Coverage next to every figure.** The share of your default-branch commits that tj could join.
35
+ Low coverage means tj is seeing part of your work. It does not mean the rest was unproductive.
36
+ - **Surfaces.** `tj optimize shipped` in the terminal, a shipped line on the `tj status` agent
37
+ card, `GET /api/v1/shipped`, commits and shipped state on the session detail route, and in Lens
38
+ the Sessions column and filter, the commit chips with a confidence glyph, the "Shipped this week"
39
+ tile and the Optimize page's Shipped card.
40
+
41
+ Nothing in the shipped finding is a saving. Every dollar in it is measured spend on sessions with
42
+ no joined commit, and a session can ship value without a commit: research, review, operations. The
43
+ caveat prints on every surface, and the finding sits outside the recoverable-waste rollup.
44
+
45
+ ## First run and onboarding
46
+
47
+ - **`tj init` is the primary name.** One command object registered under two names, so `tj init`
48
+ and `tj onboard` take the same flags, ask the same questions and write the same config. Nothing
49
+ about `tj onboard` changed.
50
+ - **`tj init --hooks`** installs a `prepare-commit-msg` hook in the current repo so a commit you
51
+ make from a plain shell mid-session carries a `TokenJam-Session:` trailer. That joins it to the
52
+ session at deterministic confidence, which is the cheapest way to raise coverage. The hook lives
53
+ in a managed block, keeps a hook you already have, and refuses a `core.hooksPath` inside the
54
+ worktree because that is a tracked directory.
55
+ - **`tj init --notes`** adds a `post-commit` hook that writes the session's measured cost to
56
+ `refs/notes/tokenjam`. It implies `--hooks` and is off unless you ask for it. tj reads
57
+ `refs/notes/ai` (Git AI) and `refs/notes/exceeds-ink` too, so a repo already annotated by one of
58
+ those gets a stronger join with no setup. The hook reads the cost through the daemon, so it skips
59
+ in a few milliseconds when `tj serve` is not running and the commit gets its trailer but no note.
60
+ - **`tj commit-note [sha]`** writes that note by hand, for a commit the hook skipped or for a repo
61
+ with no hook installed. It never fails the commit it runs from.
62
+ - **`tj init --enforce`** turns on the enforcement proxy in suggest mode and prints what it does
63
+ and does not touch. Suggest mode forwards every request unmodified and records what a policy
64
+ would have done. Nothing is blocked or rewritten until you approve it. Subscription-plan traffic
65
+ is never intercepted and subscription OAuth credentials are never proxied or forwarded.
66
+ - **`tj init --cloud <key> --org <org>`** connects the machine to a TokenJam Cloud organization.
67
+ The daemon then forwards spans, sessions and the commit joins, resumable from a per-stream
68
+ high-water mark, so a machine that was offline catches up on its own. Before the first byte
69
+ leaves, the command prints what does and does not cross and waits for a yes. Token counts, model
70
+ names, cost, timestamps, tool names, file paths, identifiers, the hashed developer id and the git
71
+ author email leave. Prompt text, completions, tool outputs, file contents, diffs and secrets do
72
+ not, unless you turn on both your local capture toggles and `forward_content`.
73
+ `tj init --cloud off` stops forwarding in place.
74
+ - **Existing installs fill in.** The daemon refills repo context on sessions that were ingested
75
+ before any of this existed, and `tj init --cloud` refills and matches before its first push. You
76
+ get history rather than a ledger that starts the day you upgraded.
77
+ - **`tj doctor` and `tj uninstall` cover the new surfaces.** doctor reports hook state per repo,
78
+ whether a hand commit right now would carry a trailer, and whether the Cloud endpoint is
79
+ reachable and the key accepted. uninstall strips the managed blocks from every hooks directory tj
80
+ wrote to.
81
+
82
+ ## Correctness
83
+
84
+ - An inherited session trailer now ranks below the tool span that ran the commit. A subagent
85
+ inherits its parent's session id, so a commit the subagent's own Bash tool ran carried the
86
+ parent's trailer and the parent absorbed it at top confidence. Such a row is now written at
87
+ `inferred`.
88
+ - Remote normalisation drops the query and fragment, and branch endpoints are picked by timestamp
89
+ rather than by file order (#762).
90
+ - The Cloud forwarder resumes in arrival order rather than event order, so a backfill that inserts
91
+ spans older than everything already sent no longer loses them. Resume marks are scoped to the
92
+ organization and to the database file. A batch the receiver refuses is split until the bad record
93
+ is isolated, then skipped and counted, so one row cannot wedge the stream.
94
+ - `sessions.updated_at` moves only when a session value actually changes, which stops the bridge
95
+ re-sending untouched rows forever.
96
+ - The transcript catch-up runs once per process, over a window-bounded tool-span index, with
97
+ producers keyed by repo.
98
+ - The serve-mode shim gates its write routes with the ingest secret rather than the optional API
99
+ key, and the backfill hand-off goes through the data-access seam instead of around it.
100
+ - `tj init --cloud` says so when history leaves without an install id.
101
+ - Lens: the hero call to action resolves to the surface that renders the analyzer, instead of a
102
+ retired route.
103
+
104
+ ## Docs
105
+
106
+ New pages for the ledger, the commit hooks and notes, and the Cloud bridge, plus the ledger OTel
107
+ attributes in the architecture reference. See `docs/ledger/`.
108
+
109
+ ## Upgrading
110
+
111
+ `pipx install --upgrade tokenjam`, or `pip install -U tokenjam` in a venv. Schema changes are
112
+ additive, so an existing database is migrated in place. Everything new in this release is opt-in:
113
+ the hooks, the notes and the Cloud bridge stay off until you run the flag that turns them on.
@@ -30,6 +30,12 @@ Configure where alerts go in `.tj/config.toml`. Multiple channels work simultane
30
30
  type = "ntfy"
31
31
  topic = "my-agent-alerts"
32
32
 
33
+ # Mast pager app for iPhone and Android. Free, with or without an account (limits below).
34
+ # The key in the URL is the only credential.
35
+ [[alerts.channels]]
36
+ type = "mast"
37
+ channel_url = "https://mast.tissue.dev/mk_0123456789abcdef0123456789abcdef01234567"
38
+
33
39
  # Discord webhook
34
40
  [[alerts.channels]]
35
41
  type = "discord"
@@ -56,6 +62,51 @@ path = "~/.tj/alerts.log"
56
62
  type = "stdout"
57
63
  ```
58
64
 
65
+ ### Mast
66
+
67
+ [Mast](https://tissue.systems/mast) is a pager app for iPhone and Android. Install it, make a
68
+ channel, and paste the channel URL into the config above. It works without an account, but a
69
+ channel made that way is lost if the app is reinstalled, and the only sign on this side is a
70
+ "No such channel." line in the log. Sign in to a free Tissue account if you want the channel
71
+ to survive that.
72
+
73
+ Both ways are free but capped. With no account you get 2 channels and 1,000 messages a month;
74
+ a free account gets 10 channels and 10,000 messages. Mast keeps accepting sends past the monthly
75
+ number, but if your agents alert a lot, check [Mast's limits](https://tissue.systems/mast/docs/limits/)
76
+ before relying on it.
77
+
78
+ `tj` posts a JSON body with `title`, `body`, `priority` and `key`. Mast documents those fields
79
+ on its [sending page](https://tissue.systems/mast/docs/send/), which is the place to look if
80
+ sends start failing.
81
+
82
+ `tj` maps severity onto three of Mast's four priorities: `info` sends `quiet`, `warning`
83
+ sends `normal`, `critical` sends `loud`. Nothing maps to the fourth, `page`. It repeats until
84
+ someone acks it and ignores mute and quiet hours, so you have to ask for it, which is what
85
+ you'd do on a channel that's meant to wake someone up:
86
+
87
+ ```toml
88
+ [[alerts.channels]]
89
+ type = "mast"
90
+ channel_url = "https://mast.tissue.dev/mk_..."
91
+ priority = "page"
92
+ min_severity = "critical"
93
+ ```
94
+
95
+ Each channel also has a ceiling, shown as **Highest priority** in the app, and a send that
96
+ asks for more than that is delivered at the ceiling. It's set when the channel is created. The
97
+ iOS app doesn't go below `loud`, the Android app uses whatever default priority you picked, and
98
+ a channel made from an API token starts at `loud`. So a channel created on Android with the
99
+ default of `Normal` will deliver `critical` alerts as `normal`, and `priority = "page"` won't
100
+ page anyone until you raise the ceiling on the phone. Worth checking before you rely on it.
101
+
102
+ Each send carries a dedupe key built from the same things the cooldown uses: the alert type,
103
+ the agent, and for `cost_budget_session` and `session_duration` the session too. If the same
104
+ alert fires again inside the channel's dedupe window (5 minutes unless you change it), Mast
105
+ adds to the count on the card already on the phone instead of sending a new one. Two sessions
106
+ over their own budget are different alerts, so they get separate cards. The default cooldown
107
+ is 60 seconds, so a repeat usually lands inside the window; if you raise `cooldown_seconds`
108
+ past the window, repeats arrive as new cards.
109
+
59
110
  ## Sensitive actions
60
111
 
61
112
  Define which tool calls should trigger immediate alerts:
@@ -88,7 +139,7 @@ Cooldown state survives a daemon restart: `AlertEngine` rehydrates it from the p
88
139
 
89
140
  ## Content stripping
90
141
 
91
- By default, alert payloads sent to external channels (Discord, Telegram, webhook, ntfy) have sensitive content stripped: `prompt_content`, `completion_content`, `tool_input`, `tool_output`. To include full content:
142
+ By default, alert payloads sent to external channels (Discord, Telegram, webhook, ntfy, Mast) have sensitive content stripped: `prompt_content`, `completion_content`, `tool_input`, `tool_output`. To include full content:
92
143
 
93
144
  ```toml
94
145
  [alerts]
@@ -35,7 +35,7 @@ flowchart TD
35
35
  Ingest["IngestPipeline\nSanitization · Session continuity · Attribute extraction"]
36
36
 
37
37
  Ingest --> Cost["CostEngine\npricing.toml"]
38
- Ingest --> Alerts["AlertEngine\n13 types · 6 channels"]
38
+ Ingest --> Alerts["AlertEngine\n13 types · 7 channels"]
39
39
  Ingest --> Schema["SchemaValidator\nexplicit JSON Schema"]
40
40
 
41
41
  Cost --> DB["DuckDB\nlocal · embedded"]
@@ -179,7 +179,7 @@ The alert engine evaluates rules after every span ingest. Alert types fall into
179
179
 
180
180
  ### Dispatch and cooldown
181
181
 
182
- `AlertDispatcher` routes fired alerts to 6 channel types: stdout, file, ntfy, webhook, Discord, Telegram. `CooldownTracker` prevents alert storms by suppressing repeat alerts of the same type for the same agent within a configurable window. Suppressed alerts are still persisted to the database but not dispatched.
182
+ `AlertDispatcher` routes fired alerts to 7 channel types: stdout, file, ntfy, webhook, Discord, Telegram, Mast. `CooldownTracker` prevents alert storms by suppressing repeat alerts of the same type for the same agent within a configurable window. Suppressed alerts are still persisted to the database but not dispatched.
183
183
 
184
184
  Content stripping removes `prompt_content`, `completion_content`, `tool_input`, `tool_output` from payloads sent to external channels unless `alerts.include_captured_content = true`. Stdout and file channels always receive the full payload.
185
185
 
@@ -426,6 +426,88 @@ Renderers (`tj optimize`, `tj cost`, the web UI cost views) read `pricing_mode`
426
426
 
427
427
  `SessionRecord.plan_tier` defaults to `unknown` for backfilled rows (no plan signal in the source data). `tj status` surfaces a one-line note when unknown-tier sessions exist; `tj optimize` refuses to render dollar figures for those sessions until the user resolves them via `tj onboard --reconfigure`.
428
428
 
429
+ Optimize analyzers do not see unattributed spend; use `tj cost --group-by session` to inspect it.
430
+
431
+ ---
432
+
433
+ ## OTel semconv extensions: repo context and developer identity
434
+
435
+ The shipped-value ledger needs to know which repo a session ran in and who ran it. That is a second
436
+ group of attribute names, defined in `TjAttributes` and `ResourceAttributes` in
437
+ `tokenjam/otel/semconv.py`, using the standard OTel spelling wherever one exists (`vcs.*`,
438
+ `user.email`, `host.name`) and `tokenjam.*` for the rest. Every one of them is optional: a value
439
+ that cannot be resolved is absent rather than a placeholder, so a downstream join can never match on
440
+ something invented.
441
+
442
+ **Where the values actually come from.** These names are not emitted by an agent wrapper. There are
443
+ three paths, and it is worth being precise about which is which:
444
+
445
+ - **Claude Code and Codex.** Nothing is stamped at emission time. The backfill and the daemon's
446
+ transcript catch-up derive the values from the transcript's `cwd` and branch
447
+ (`core/repo_context.py::session_context_for_cwd`) and write them straight onto the session row.
448
+ Sessions ingested before the columns existed are filled in later by
449
+ `core/transcript_sync.py::refill_session_context`.
450
+ - **Producers that stamp the names themselves.** The ingest path reads them off with
451
+ `session_context_from_attrs` and stores them on the session. Nothing in the Python or TypeScript
452
+ SDK sets them for you today, so this is for a producer that chooses to send them, and **the level
453
+ they have to be set at depends on the route**:
454
+
455
+ | Route | Reads from |
456
+ |---|---|
457
+ | in-process SDK exporter (`otel/provider.py`) | **resource attributes only** |
458
+ | Claude Code OTLP logs route (`api/routes/logs.py`) | **resource attributes only** |
459
+ | OTLP JSON span ingest (`otel/otlp_parsing.py`) | resource **or** span attributes, merged, span wins on conflict |
460
+
461
+ Set them at resource level. That is the one placement every route reads. A producer that puts them
462
+ on individual spans and exports through the in-process SDK loses its repo and developer context
463
+ silently, because the resource carries none of them and nothing errors.
464
+ - **Outbound to Cloud.** The bridge maps the stored session columns back onto these attribute names
465
+ on the wire, and adds `tokenjam.install_id` and `host.name` to the resource at that point.
466
+
467
+ `tj otel-resource-attrs` is **not** part of this. It prints `service.name`, plus
468
+ `service.namespace` when the project is set in config, and nothing else. The per-terminal `claude`
469
+ wrapper exports its output as `OTEL_RESOURCE_ATTRIBUTES`, which is how concurrent terminals land as
470
+ distinct tiles; the ledger columns arrive by the transcript path above, not through that variable.
471
+
472
+ **The attribute names, per process:**
473
+
474
+ | Attribute | Value | Source |
475
+ |---|---|---|
476
+ | `user.email` | git author email | `git config user.email` in the session cwd, else the global value, else absent |
477
+ | `tokenjam.developer_id` | `sha256(lower(user.email))[:16]` | derived; the pseudonymous id every ledger surface uses |
478
+ | `tokenjam.install_id` | uuid4, generated once | `~/.tj/install_id`; added to the resource by the Cloud bridge |
479
+ | `host.name` | hostname | `socket.gethostname()`; added to the resource by the Cloud bridge |
480
+ | `tokenjam.github_login` | GitHub login | reserved. Defined in `TjAttributes`, not set by this build |
481
+ | `vcs.repository.url.full` | normalised remote, `https://github.com/org/repo`, no `.git`, no credentials, no query or fragment | `git remote get-url origin` |
482
+ | `vcs.repository.name` | `org/repo` | derived from the remote |
483
+
484
+ **The attribute names, per session:**
485
+
486
+ | Attribute | Value |
487
+ |---|---|
488
+ | `vcs.ref.head.name` | branch at session start |
489
+ | `vcs.ref.head.revision` | HEAD sha at session start, only when the source records it. Codex rollouts do; Claude Code transcripts do not, and it is absent rather than guessed. The join keys on repo, branch and time, never on this sha |
490
+ | `tokenjam.repo_root` | absolute path of the repo root |
491
+ | `tokenjam.session.branch_end` | branch at session end |
492
+ | `tokenjam.session.head_end` | HEAD sha at session end |
493
+
494
+ **Never stamped by the client:** team, department, cost centre, display name. Those are org-side
495
+ maps and have no business on a local span.
496
+
497
+ `user.email` is the one personal identifier here. It stays on your machine unless you connect
498
+ [the Cloud bridge](ledger/cloud-bridge.md), which states it in the list it prints before the first
499
+ byte leaves.
500
+
501
+ ### Ledger storage
502
+
503
+ `sessions` carries the same values as nullable columns (`repo_remote`, `repo_root`, `branch_start`,
504
+ `branch_end`, `head_sha_start`, `head_sha_end`, `developer_id`, `user_email`), and the
505
+ `session_commits` table holds the join, keyed `(session_id, commit_sha)` with its `confidence`,
506
+ `source`, author email, commit time and match delta. Three side tables keep every read in SQL: a
507
+ default-branch commit index, per-commit file statistics for the rework figure, and a per-session
508
+ scan watermark. Migrations are additive, as everywhere else in the schema. See
509
+ [the ledger overview](ledger/overview.md).
510
+
429
511
  ---
430
512
 
431
513
  ## SDK cost-attribution dimensions (multi-tenant cost breakdown)
@@ -7,13 +7,15 @@ Imports [Langfuse](https://langfuse.com) observations into the local TokenJam DB
7
7
  ```bash
8
8
  tj backfill langfuse \
9
9
  --source-url https://cloud.langfuse.com \
10
- --api-key lf_pk_... \
10
+ --api-key pk-lf-...:sk-lf-... \
11
11
  --since 30d
12
12
  ```
13
13
 
14
- Reads from Langfuse's public REST endpoint (`/api/public/observations`) with Bearer-auth. Follows pagination automatically.
14
+ Reads from Langfuse's Observations API v2 (`/api/public/v2/observations`) and follows its cursors automatically. The key is the project's public and secret key joined with a colon (`PUBLIC_KEY:SECRET_KEY`) and is sent with Basic auth. A Bearer public key only gets a scores-only scope in Langfuse, so it cannot read observations; a value without a colon is still sent as a Bearer token for proxies that expect one.
15
15
 
16
- The `--source-url` value can be the bare base URL (`https://cloud.langfuse.com`) — the adapter appends `/api/public/observations`. Self-hosted Langfuse instances work the same way.
16
+ Langfuse Cloud removes the older observations endpoint on 16 November 2026, so v2 is the endpoint to rely on. For a self-hosted server that has no v2 endpoint (it answers 404), the adapter falls back to `/api/public/observations` with page numbers.
17
+
18
+ The `--source-url` value can be the bare base URL (`https://cloud.langfuse.com`) — the adapter appends the API path. A URL that already ends in `/api/public/observations` still works. Self-hosted Langfuse instances work the same way.
17
19
 
18
20
  `--since` accepts the same syntax as `tj cost --since`: `30d`, `24h`, or an ISO-8601 timestamp.
19
21
 
@@ -45,9 +47,9 @@ Each Langfuse `Observation` becomes one TokenJam span:
45
47
  | `type` (`GENERATION` / `SPAN` / `EVENT`) | `kind` + `name` |
46
48
  | `startTime` / `endTime` | `start_time` / `end_time` |
47
49
  | `model` | `model`, `provider` (derived), `billing_account` (derived) |
48
- | `usage.input` / `usage.output` | `input_tokens` / `output_tokens` |
50
+ | `usageDetails.input` / `usageDetails.output` (v2), or `usage.input` / `usage.output` (v1) | `input_tokens` / `output_tokens` |
49
51
  | `usageDetails.input_cache_read` | `cache_tokens` |
50
- | `calculatedTotalCost` | `cost_usd` |
52
+ | `totalCost` (v2) or `calculatedTotalCost` (v1) | `cost_usd` |
51
53
  | `level` / `statusMessage` | `status_code` / `status_message` |
52
54
 
53
55
  `billing_account` is derived from the model name (`claude-*` → `anthropic`, `gpt-*`/`o3`/`o4` → `openai`, `gemini-*` → `google`). Unknown models leave it `NULL`; affected sessions will surface as `plan_tier = 'unknown'` in `tj optimize`.