stacktrace-cli 0.9.0__tar.gz → 0.10.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (531) hide show
  1. stacktrace_cli-0.10.0/.github/workflows/bedrock-live.yml +55 -0
  2. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/CLAUDE.md +3 -2
  3. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/PKG-INFO +23 -7
  4. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/README.md +20 -4
  5. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0006-trust-boundary-and-detection-upload.md +1 -1
  6. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0031-one-host-daemon-observes-native-session-logs.md +1 -1
  7. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0037-reuse-openaidr-append-cursors-in-the-daemon.md +1 -1
  8. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0038-poll-normalized-sessions-for-supplemental-changes.md +1 -1
  9. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0045-scan-every-session-and-outlive-them.md +1 -1
  10. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0061-the-drain-sends-findings-only.md +1 -1
  11. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0065-asset-external-id-resolves-by-a-ladder.md +1 -1
  12. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0078-a-seeded-display-prefix-replaces-the-hostname-label.md +1 -1
  13. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0092-cost-is-its-own-rule-family.md +1 -1
  14. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0093-environment-cost-baselines-count-tokens-keyed-by-model.md +1 -1
  15. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0096-cost-usage-may-leave-as-token-totals-and-work-identifiers.md +1 -1
  16. stacktrace_cli-0.10.0/docs/adrs/0101-what-names-a-run-in-fleet.md +111 -0
  17. stacktrace_cli-0.10.0/docs/adrs/0102-token-use-is-never-compared-with-a-providers-usage-api.md +55 -0
  18. stacktrace_cli-0.10.0/docs/adrs/0103-finished-runs-may-leave-as-numbers-for-org-baselines.md +91 -0
  19. stacktrace_cli-0.10.0/docs/adrs/0104-usage-is-its-own-upload.md +92 -0
  20. stacktrace_cli-0.10.0/docs/adrs/0105-an-asset-key-is-a-bare-uuid.md +76 -0
  21. stacktrace_cli-0.10.0/docs/adrs/0106-boot-id-is-salted-with-the-pid-namespace.md +69 -0
  22. stacktrace_cli-0.10.0/docs/adrs/0107-the-daemon-follows-every-kind-openaidr-reads.md +114 -0
  23. stacktrace_cli-0.10.0/docs/adrs/0108-a-kind-renamed-before-any-release-read-it-keeps-no-alias.md +68 -0
  24. stacktrace_cli-0.10.0/docs/adrs/0109-a-detection-carries-its-runs-title-and-the-persons-name.md +106 -0
  25. stacktrace_cli-0.10.0/docs/adrs/0110-every-kinds-account-comes-from-openaidr.md +70 -0
  26. stacktrace_cli-0.10.0/docs/adrs/0111-built-in-sub-agents-and-skills-come-from-the-bom.md +74 -0
  27. stacktrace_cli-0.10.0/docs/adrs/0112-a-person-is-known-by-the-accounts-on-the-host.md +137 -0
  28. stacktrace_cli-0.10.0/docs/adrs/0113-size-triggers-behaviour-explains-session-cost-carries-reasons.md +103 -0
  29. stacktrace_cli-0.10.0/docs/adrs/0114-similar-sessions-are-the-same-agent-in-the-same-repo.md +79 -0
  30. stacktrace_cli-0.10.0/docs/adrs/0115-usage-states-its-coverage-and-fleet-returns-expected-runs.md +93 -0
  31. stacktrace_cli-0.10.0/docs/adrs/0116-a-component-row-carries-what-its-results-cost-under-one-closed-key.md +84 -0
  32. stacktrace_cli-0.10.0/docs/adrs/0117-a-component-row-on-the-day-of-a-switch-counts-from-the-switch.md +60 -0
  33. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/INDEX.md +22 -5
  34. stacktrace_cli-0.10.0/docs/plans/017-cost-phase-2.md +325 -0
  35. stacktrace_cli-0.10.0/docs/releases/v0.10.0.md +136 -0
  36. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/specs/correlation.md +9 -2
  37. stacktrace_cli-0.10.0/docs/specs/cost-notifications.md +721 -0
  38. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/specs/cost-phase-1.md +54 -23
  39. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/specs/cost-phase-2.md +38 -7
  40. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/specs/cost.md +92 -66
  41. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/specs/daemon-store.md +10 -0
  42. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/specs/daemon-uploads.md +5 -0
  43. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/specs/detection-policies.md +49 -55
  44. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/specs/detection-upload.md +24 -1
  45. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/specs/detector.md +11 -8
  46. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/specs/monitor.md +211 -46
  47. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/specs/notification-delivery.md +1 -1
  48. stacktrace_cli-0.10.0/docs/specs/usage-upload.md +401 -0
  49. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/pyproject.toml +19 -3
  50. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/__init__.py +1 -1
  51. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/cloud/setup.sh +5 -3
  52. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/correlate/acquire.py +7 -1
  53. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/correlate/composition.py +46 -1
  54. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/correlate/join.py +102 -147
  55. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/correlate/observed.py +18 -19
  56. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/correlate/orchestrate.py +45 -18
  57. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/cost/baseline.py +174 -112
  58. stacktrace_cli-0.10.0/src/stacktrace_cli/cost/component_usage.py +324 -0
  59. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/cost/components.py +5 -5
  60. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/cost/measures.py +8 -5
  61. stacktrace_cli-0.10.0/src/stacktrace_cli/cost/org_baselines.py +258 -0
  62. stacktrace_cli-0.10.0/src/stacktrace_cli/cost/reasons.py +592 -0
  63. stacktrace_cli-0.10.0/src/stacktrace_cli/cost/rules.py +662 -0
  64. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/cost/runs.py +44 -21
  65. stacktrace_cli-0.10.0/src/stacktrace_cli/cost/usage.py +293 -0
  66. stacktrace_cli-0.10.0/src/stacktrace_cli/daemon/accounts.py +269 -0
  67. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/daemon/cli.py +46 -15
  68. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/daemon/client.py +41 -0
  69. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/daemon/composition.py +53 -1
  70. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/daemon/config.py +11 -2
  71. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/daemon/costs.py +194 -296
  72. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/daemon/db.py +250 -0
  73. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/daemon/fleet.py +85 -21
  74. stacktrace_cli-0.10.0/src/stacktrace_cli/daemon/observer.py +755 -0
  75. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/daemon/presentation.py +49 -3
  76. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/daemon/runtime.py +153 -17
  77. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/daemon/scan.py +1 -1
  78. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/daemon/server.py +17 -3
  79. stacktrace_cli-0.10.0/src/stacktrace_cli/daemon/store.py +2440 -0
  80. stacktrace_cli-0.10.0/src/stacktrace_cli/daemon/usage.py +1126 -0
  81. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/daemon/webhook.py +2 -2
  82. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/detector/cache.py +4 -0
  83. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/detector/deterministic.py +11 -12
  84. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/detector/prompts/__init__.py +0 -5
  85. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/detector/reasoning.py +4 -4
  86. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/detector/rules.py +12 -15
  87. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/detector/run.py +2 -2
  88. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/detector/windows.py +3 -3
  89. stacktrace_cli-0.10.0/src/stacktrace_cli/monitor/costs.py +650 -0
  90. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/monitor/render.py +69 -25
  91. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/monitor/server.py +14 -1
  92. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/monitor/site/app.js +516 -135
  93. stacktrace_cli-0.10.0/src/stacktrace_cli/monitor/site/cost.js +1008 -0
  94. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/monitor/site/fonts/OFL.txt +196 -97
  95. stacktrace_cli-0.10.0/src/stacktrace_cli/monitor/site/fonts/playfair-display-600-italic-latin.woff2 +0 -0
  96. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/monitor/site/index.html +35 -11
  97. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/monitor/site/inventory.js +5 -2
  98. stacktrace_cli-0.10.0/src/stacktrace_cli/monitor/site/styles.css +902 -0
  99. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/monitor/watch.py +39 -12
  100. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/private_state.py +2 -3
  101. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/remote/client.py +93 -1
  102. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/remote/detect_payload.py +34 -14
  103. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/remote/identity.py +39 -31
  104. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/remote/redact.py +0 -7
  105. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/remote/spool.py +8 -6
  106. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/remote/upload_contract.py +136 -4
  107. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/sessions/access.py +96 -0
  108. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/sessions/protocols.py +18 -0
  109. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/telemetry/events.py +3 -0
  110. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/agent_bom_fixture.py +10 -1
  111. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/conftest.py +22 -0
  112. stacktrace_cli-0.10.0/tests/cost/scenarios.py +313 -0
  113. stacktrace_cli-0.10.0/tests/cost/test_as_of_cuts_every_timed_collection.py +150 -0
  114. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/cost/test_baseline.py +86 -48
  115. stacktrace_cli-0.10.0/tests/cost/test_component_usage.py +307 -0
  116. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/cost/test_cost_evidence_travels.py +22 -22
  117. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/cost/test_cost_findings_are_dated_by_their_citations.py +56 -187
  118. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/cost/test_cost_findings_carry_no_session_text.py +41 -38
  119. stacktrace_cli-0.10.0/tests/cost/test_org_baselines.py +333 -0
  120. stacktrace_cli-0.10.0/tests/cost/test_reasons.py +261 -0
  121. stacktrace_cli-0.10.0/tests/cost/test_rules_baseline.py +189 -0
  122. stacktrace_cli-0.10.0/tests/cost/test_usage.py +255 -0
  123. stacktrace_cli-0.10.0/tests/daemon/observing.py +47 -0
  124. stacktrace_cli-0.10.0/tests/daemon/test_accounts.py +530 -0
  125. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/daemon/test_activity_log.py +5 -6
  126. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/daemon/test_cli.py +78 -7
  127. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/daemon/test_client.py +58 -0
  128. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/daemon/test_composition.py +79 -1
  129. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/daemon/test_config.py +12 -2
  130. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/daemon/test_costs.py +327 -487
  131. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/daemon/test_db.py +42 -0
  132. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/daemon/test_detection_needs_no_subscriber.py +4 -2
  133. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/daemon/test_fleet.py +151 -0
  134. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/daemon/test_observer.py +480 -50
  135. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/daemon/test_runtime.py +116 -17
  136. stacktrace_cli-0.10.0/tests/daemon/test_session_cost_notices.py +117 -0
  137. stacktrace_cli-0.10.0/tests/daemon/test_subagent_routing.py +154 -0
  138. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/daemon/test_the_drained_payload_is_the_cold_one.py +5 -4
  139. stacktrace_cli-0.10.0/tests/daemon/test_usage.py +1768 -0
  140. stacktrace_cli-0.10.0/tests/daemon/test_usage_store.py +973 -0
  141. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/daemon/test_webhook.py +2 -1
  142. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/detector_session_fixture.py +18 -24
  143. stacktrace_cli-0.10.0/tests/monitor/cost_harness.mjs +288 -0
  144. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/monitor/feed_harness.mjs +334 -1
  145. stacktrace_cli-0.10.0/tests/monitor/test_cost_page.py +548 -0
  146. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/monitor/test_cost_range_switch.py +17 -7
  147. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/monitor/test_feed_model.py +232 -5
  148. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/monitor/test_render.py +14 -13
  149. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/monitor/test_render_cost.py +340 -44
  150. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/monitor/test_site_assets.py +69 -34
  151. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/monitor/test_watch.py +112 -2
  152. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/remote/test_client.py +51 -0
  153. stacktrace_cli-0.10.0/tests/remote/test_cloud_setup_asset_id.py +56 -0
  154. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/remote/test_detect_activity.py +2 -2
  155. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/remote/test_detect_contract_is_exhaustive.py +16 -2
  156. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/remote/test_facade_contract.py +12 -0
  157. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/remote/test_identity.py +119 -42
  158. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/remote/test_seam.py +6 -0
  159. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/remote/test_spool.py +12 -0
  160. stacktrace_cli-0.10.0/tests/remote/test_usage_client.py +111 -0
  161. stacktrace_cli-0.10.0/tests/remote/test_usage_contract.py +283 -0
  162. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/telemetry/test_every_derived_site.py +20 -0
  163. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/telemetry/test_hooks.py +5 -2
  164. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_acquire.py +11 -0
  165. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_call_status_conventions.py +3 -2
  166. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_correlate_orchestrate.py +54 -1
  167. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_correlate_render.py +5 -0
  168. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_correlated_session.py +5 -0
  169. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_detection_subject.py +6 -2
  170. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_detector_priors.py +0 -35
  171. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_fingerprint_covers_what_the_analyzer_reads.py +3 -0
  172. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_join.py +82 -4
  173. stacktrace_cli-0.10.0/tests/test_kind_conformance.py +163 -0
  174. stacktrace_cli-0.10.0/tests/test_no_agent_kind_is_named.py +83 -0
  175. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_observed.py +5 -0
  176. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_openaca_contract.py +7 -0
  177. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_openaidr_contract.py +14 -0
  178. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_project_map.py +5 -0
  179. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_session_identity_is_the_pair.py +9 -0
  180. stacktrace_cli-0.10.0/tests/test_signed_in_asks_the_agent.py +93 -0
  181. stacktrace_cli-0.10.0/tests/tool_fields.py +25 -0
  182. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/uv.lock +9 -9
  183. stacktrace_cli-0.9.0/.claude/skills/pr-review-loop/SKILL.md +0 -120
  184. stacktrace_cli-0.9.0/docs/plans/017-cost-phase-2.md +0 -89
  185. stacktrace_cli-0.9.0/src/stacktrace_cli/cost/rules.py +0 -1138
  186. stacktrace_cli-0.9.0/src/stacktrace_cli/daemon/observer.py +0 -670
  187. stacktrace_cli-0.9.0/src/stacktrace_cli/daemon/store.py +0 -1209
  188. stacktrace_cli-0.9.0/src/stacktrace_cli/monitor/costs.py +0 -375
  189. stacktrace_cli-0.9.0/src/stacktrace_cli/monitor/site/cost.js +0 -436
  190. stacktrace_cli-0.9.0/src/stacktrace_cli/monitor/site/styles.css +0 -586
  191. stacktrace_cli-0.9.0/tests/cost/scenarios.py +0 -169
  192. stacktrace_cli-0.9.0/tests/cost/test_rules_baseline.py +0 -535
  193. stacktrace_cli-0.9.0/tests/monitor/cost_harness.mjs +0 -133
  194. stacktrace_cli-0.9.0/tests/monitor/test_cost_page.py +0 -232
  195. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/.agents/skills/release-stacktrace/SKILL.md +0 -0
  196. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/.claude/settings.json +0 -0
  197. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/.claude/skills/release-stacktrace/SKILL.md +0 -0
  198. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/.codex/hooks.json +0 -0
  199. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/.github/managed-autofix.md +0 -0
  200. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/.github/pull_request_template.md +0 -0
  201. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/.github/workflows/ci.yml +0 -0
  202. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/.github/workflows/publish-pypi.yml +0 -0
  203. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/.gitignore +0 -0
  204. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/AGENTS.md +0 -0
  205. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0001-session-telemetry-as-input.md +0 -0
  206. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0002-session-collection-in-openaidr.md +0 -0
  207. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0003-runtime-edges.md +0 -0
  208. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0004-three-stage-detector.md +0 -0
  209. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0005-detection-family-and-report-assembly.md +0 -0
  210. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0007-proprietary-package-on-open-dependencies.md +0 -0
  211. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0008-console-in-separate-demo-package.md +0 -0
  212. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0010-detection-severity-and-confidence-ladders.md +0 -0
  213. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0011-verdict-cache.md +0 -0
  214. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0012-observation-evidence-kinds-and-transport.md +0 -0
  215. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0013-rule-catalogue-triage-and-per-rule-context.md +0 -0
  216. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0014-declared-project-mapping.md +0 -0
  217. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0015-narrow-the-security-catalogue.md +0 -0
  218. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0016-stall-grouping-is-session-wide.md +0 -0
  219. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0017-a-declined-repeat-is-a-stall.md +0 -0
  220. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0018-remote-sync-config-and-facade-consumption.md +0 -0
  221. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0019-delegated-commands-are-openaca-objects.md +0 -0
  222. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0020-openaca-consumption-boundary.md +0 -0
  223. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0021-two-command-kinds.md +0 -0
  224. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0022-detection-scope-is-a-catalogue-column.md +0 -0
  225. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0023-sync-detect-collects-and-does-not-escalate.md +0 -0
  226. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0024-the-upload-carries-observations.md +0 -0
  227. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0025-a-denied-call-is-activity-never-an-invocation.md +0 -0
  228. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0026-the-console-becomes-a-product-surface.md +0 -0
  229. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0027-a-finding-may-name-what-it-could-not-place.md +0 -0
  230. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0028-the-console-shows-what-it-placed.md +0 -0
  231. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0029-stage-three-returns-to-opt-in.md +0 -0
  232. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0030-a-detection-is-dated-by-the-turns-it-cites.md +0 -0
  233. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0032-refresh-daemon-compositions-outside-detection.md +0 -0
  234. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0033-a-third-party-analyzer-only-by-a-flag-that-names-it.md +0 -0
  235. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0034-the-drift-grade-is-read-off-a-run-not-a-call.md +0 -0
  236. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0035-naming-an-analyzer-selects-stored-answers.md +0 -0
  237. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0036-deliver-eligible-findings-to-slack-from-the-daemon.md +0 -0
  238. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0039-send-usage-telemetry-by-default-with-an-opt-out.md +0 -0
  239. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0041-defer-native-windows-support.md +0 -0
  240. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0042-read-the-build-commit-from-the-install-record.md +0 -0
  241. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0043-name-the-session-agent-and-host-and-count-errors-by-class.md +0 -0
  242. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0044-send-the-build-as-version-prints-it.md +0 -0
  243. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0046-the-finding-store-is-an-append-only-queue.md +0 -0
  244. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0047-capture-activity-during-correlation-or-lose-it.md +0 -0
  245. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0048-the-daemon-keeps-a-leveled-content-free-activity-log.md +0 -0
  246. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0056-stop-a-resident-daemon-by-record-and-signal.md +0 -0
  247. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0057-grow-the-queue-schema-additively-and-share-only-the-document.md +0 -0
  248. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0058-one-word-for-a-finding-columns-for-a-counter-and-a-push-that-does-not-wait.md +0 -0
  249. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0059-the-daemon-does-not-decide-whether-it-should-be-running.md +0 -0
  250. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0060-two-upload-postures-not-one-command-with-two-sources.md +0 -0
  251. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0062-hold-the-transition-lock-across-remote-side-effects.md +0 -0
  252. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0063-underbuilt-debt-does-not-hold-the-scan-watermark.md +0 -0
  253. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0064-a-redacted-value-has-one-path-span.md +0 -0
  254. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0066-host-owned-daemon-supervision.md +0 -0
  255. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0067-a-webhook-is-an-independent-queue-subscriber.md +0 -0
  256. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0068-webhooks-retry-the-retained-backlog.md +0 -0
  257. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0069-webhooks-deliver-what-retention-holds.md +0 -0
  258. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0070-package-the-cloud-agent-environment-bootstrap.md +0 -0
  259. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0071-render-the-allowlisted-payload-per-destination.md +0 -0
  260. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0072-host-supervisors-own-daemon-restarts.md +0 -0
  261. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0073-name-what-fired-and-which-component.md +0 -0
  262. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0074-a-window-selects-findings-by-when-they-happened.md +0 -0
  263. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0076-two-phase-detection-pipeline.md +0 -0
  264. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0077-the-bom-job-wakes-once-at-startup-staggered.md +0 -0
  265. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0079-the-monitor-page-renders-findings-not-pipeline-health.md +0 -0
  266. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0080-enabling-reasoning-does-not-requeue-the-past.md +0 -0
  267. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0081-reasoning-activation-returns-to-explicit-opt-in.md +0 -0
  268. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0082-monitor-checks-every-installed-component-by-default.md +0 -0
  269. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0083-each-block-reason-is-its-own-rule.md +0 -0
  270. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0084-a-recursive-deletes-evidence-is-the-rm-that-ran.md +0 -0
  271. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0085-show-when-and-which-finding-slack-delivered.md +0 -0
  272. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0086-a-refusal-names-who-answered-the-call.md +0 -0
  273. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0087-deploy-compiled-policy-with-a-privileged-scheduled-job.md +0 -0
  274. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0088-slack-alerts-leave-out-confidence.md +0 -0
  275. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0089-infra-gate-reads-commands-not-shell-semantics.md +0 -0
  276. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0090-count-completed-commands-locate-by-ip-send-through-the-managed-proxy.md +0 -0
  277. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0091-mark-our-own-machines-and-name-what-failed.md +0 -0
  278. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0094-estimate-cost-from-tokens-the-agent-figure-is-a-cross-check.md +0 -0
  279. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0095-cost-findings-reach-fleet-each-rule-can-be-muted.md +0 -0
  280. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0097-the-daemon-makes-cost-findings-and-the-monitor-reads-them.md +0 -0
  281. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0098-a-run-is-its-main-session.md +0 -0
  282. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0099-cost-is-measured-in-tokens-and-relative-increases.md +0 -0
  283. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0100-the-monitor-runs-offline-for-the-website.md +0 -0
  284. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/HOOK-PROMPT.md +0 -0
  285. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/TEMPLATE.md +0 -0
  286. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/cutover-openaca-remote.md +0 -0
  287. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/plans/002-session-input.md +0 -0
  288. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/plans/003-correlation.md +0 -0
  289. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/plans/004-detector.md +0 -0
  290. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/plans/005-remote-sync.md +0 -0
  291. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/plans/006-cli-composition.md +0 -0
  292. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/plans/007-detection-upload.md +0 -0
  293. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/plans/008-monitor.md +0 -0
  294. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/plans/009-reasoning-jev.md +0 -0
  295. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/plans/010-session-daemon.md +0 -0
  296. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/plans/011-daemon-store.md +0 -0
  297. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/plans/012-daemon-scanning.md +0 -0
  298. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/plans/013-daemon-uploads.md +0 -0
  299. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/plans/014-asset-identity.md +0 -0
  300. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/plans/015-managed-policy-deployment.md +0 -0
  301. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/plans/016-cost-phase-1.md +0 -0
  302. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/releases/v0.0.1.md +0 -0
  303. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/releases/v0.1.0.md +0 -0
  304. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/releases/v0.2.0.md +0 -0
  305. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/releases/v0.2.1.md +0 -0
  306. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/releases/v0.2.2.md +0 -0
  307. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/releases/v0.2.3.md +0 -0
  308. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/releases/v0.3.0.md +0 -0
  309. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/releases/v0.3.1.md +0 -0
  310. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/releases/v0.4.0.md +0 -0
  311. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/releases/v0.4.1.md +0 -0
  312. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/releases/v0.5.0.md +0 -0
  313. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/releases/v0.5.1.md +0 -0
  314. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/releases/v0.5.2.md +0 -0
  315. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/releases/v0.5.3.md +0 -0
  316. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/releases/v0.6.0.md +0 -0
  317. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/releases/v0.6.1.md +0 -0
  318. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/releases/v0.7.0.md +0 -0
  319. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/releases/v0.7.1.md +0 -0
  320. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/releases/v0.8.0.md +0 -0
  321. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/releases/v0.9.0.md +0 -0
  322. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/research/001-intent-drift-metric.md +0 -0
  323. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/specs/aidr.md +0 -0
  324. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/specs/cli-composition.md +0 -0
  325. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/specs/daemon-scanning.md +0 -0
  326. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/specs/event-time.md +0 -0
  327. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/specs/managed-policy-deployment.md +0 -0
  328. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/specs/monitor-inventory.md +0 -0
  329. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/specs/reasoning-jev.md +0 -0
  330. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/specs/remote-sync.md +0 -0
  331. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/specs/session-input.md +0 -0
  332. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/scripts/cost_latency.py +0 -0
  333. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/scripts/git-hooks/pre-push +0 -0
  334. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/scripts/install-hooks.sh +0 -0
  335. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/__main__.py +0 -0
  336. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/analysis.py +0 -0
  337. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/build.py +0 -0
  338. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/cli.py +0 -0
  339. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/cloud/__init__.py +0 -0
  340. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/correlate/__init__.py +0 -0
  341. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/correlate/project_map.py +0 -0
  342. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/correlate/record.py +0 -0
  343. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/correlate/render.py +0 -0
  344. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/cost/__init__.py +0 -0
  345. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/cost/clock.py +0 -0
  346. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/cost/evidence.py +0 -0
  347. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/cost/ledger.py +0 -0
  348. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/cost/models.py +0 -0
  349. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/cost/tokens.py +0 -0
  350. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/cost/totals.py +0 -0
  351. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/daemon/__init__.py +0 -0
  352. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/daemon/activity_log.py +0 -0
  353. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/daemon/bom.py +0 -0
  354. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/daemon/identity.py +0 -0
  355. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/daemon/jobs.py +0 -0
  356. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/daemon/lifecycle.py +0 -0
  357. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/daemon/paths.py +0 -0
  358. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/daemon/protocol.py +0 -0
  359. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/daemon/service.py +0 -0
  360. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/detector/__init__.py +0 -0
  361. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/detector/analyzer.py +0 -0
  362. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/detector/blocked.py +0 -0
  363. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/detector/finding.py +0 -0
  364. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/detector/history.py +0 -0
  365. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/detector/jev.py +0 -0
  366. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/detector/priors.py +0 -0
  367. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/detector/prompts/jev-v1/stacktrace-deceptive-completion.json +0 -0
  368. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/detector/prompts/jev-v2/stacktrace-deceptive-completion.json +0 -0
  369. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/detector/prompts/jev-v2/stacktrace-infra-unsafe-action.json +0 -0
  370. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/detector/prompts/v1/exclusions.md +0 -0
  371. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/detector/prompts/v1/framing.md +0 -0
  372. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/detector/prompts/v1/stacktrace-deceptive-completion.md +0 -0
  373. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/detector/render.py +0 -0
  374. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/detector/secrets.py +0 -0
  375. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/detector/verdict.py +0 -0
  376. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/monitor/__init__.py +0 -0
  377. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/monitor/inventory.py +0 -0
  378. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/monitor/offline.py +0 -0
  379. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/monitor/reasoning.py +0 -0
  380. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/monitor/site/apple-icon.png +0 -0
  381. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/monitor/site/favicon.ico +0 -0
  382. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/monitor/site/fonts/dm-mono-400-latin.woff2 +0 -0
  383. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/monitor/site/fonts/dm-mono-500-latin.woff2 +0 -0
  384. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/monitor/site/fonts/dm-sans-latin.woff2 +0 -0
  385. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/monitor/site/icon.svg +0 -0
  386. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/monitor/state.py +0 -0
  387. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/monitor/verdicts.py +0 -0
  388. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/options.py +0 -0
  389. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/remote/__init__.py +0 -0
  390. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/remote/cli.py +0 -0
  391. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/remote/config.py +0 -0
  392. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/remote/payload.py +0 -0
  393. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/remote/policy.py +0 -0
  394. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/remote/policy_service.py +0 -0
  395. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/remote/policy_worker.py +0 -0
  396. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/remote/sync.py +0 -0
  397. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/remote/sync_detect.py +0 -0
  398. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/sessions/__init__.py +0 -0
  399. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/sessions/index.py +0 -0
  400. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/sessions/lineage.py +0 -0
  401. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/sessions/outcome.py +0 -0
  402. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/sessions/render.py +0 -0
  403. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/telemetry/__init__.py +0 -0
  404. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/telemetry/cli.py +0 -0
  405. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/telemetry/posthog.py +0 -0
  406. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/telemetry/state.py +0 -0
  407. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/webhook/__init__.py +0 -0
  408. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/webhook/cli.py +0 -0
  409. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/webhook/config.py +0 -0
  410. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/__init__.py +0 -0
  411. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/cost/__init__.py +0 -0
  412. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/cost/fakes.py +0 -0
  413. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/cost/test_clock.py +0 -0
  414. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/cost/test_components.py +0 -0
  415. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/cost/test_cost_is_tokens.py +0 -0
  416. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/cost/test_cost_latency.py +0 -0
  417. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/cost/test_evidence.py +0 -0
  418. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/cost/test_ledger.py +0 -0
  419. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/cost/test_measures.py +0 -0
  420. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/cost/test_models.py +0 -0
  421. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/cost/test_rules_budget.py +0 -0
  422. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/cost/test_runs.py +0 -0
  423. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/cost/test_totals.py +0 -0
  424. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/daemon/__init__.py +0 -0
  425. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/daemon/test_cost_guidance.py +0 -0
  426. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/daemon/test_identity.py +0 -0
  427. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/daemon/test_job_thread.py +0 -0
  428. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/daemon/test_jobs.py +0 -0
  429. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/daemon/test_lifecycle.py +0 -0
  430. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/daemon/test_queue_reader.py +0 -0
  431. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/daemon/test_scan.py +0 -0
  432. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/daemon/test_service.py +0 -0
  433. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/daemon/test_socket.py +0 -0
  434. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/daemon/test_stage_times.py +0 -0
  435. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/daemon/test_store.py +0 -0
  436. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/daemon/test_the_stored_row_is_sufficient.py +0 -0
  437. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/daemon/test_wire_frames_are_bounded.py +0 -0
  438. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/monitor/__init__.py +0 -0
  439. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/monitor/inventory_harness.mjs +0 -0
  440. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/monitor/test_inventory.py +0 -0
  441. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/monitor/test_inventory_page.py +0 -0
  442. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/monitor/test_offline.py +0 -0
  443. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/monitor/test_reasoning_gates.py +0 -0
  444. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/monitor/test_server.py +0 -0
  445. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/monitor/test_state.py +0 -0
  446. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/monitor/test_verdicts.py +0 -0
  447. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/remote/__init__.py +0 -0
  448. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/remote/helpers.py +0 -0
  449. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/remote/test_cli.py +0 -0
  450. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/remote/test_config.py +0 -0
  451. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/remote/test_detect_cli.py +0 -0
  452. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/remote/test_detect_client.py +0 -0
  453. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/remote/test_detect_gate_matches_the_cloud.py +0 -0
  454. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/remote/test_detect_layers_compose.py +0 -0
  455. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/remote/test_detect_payload_reaches_the_cloud_model.py +0 -0
  456. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/remote/test_detect_redaction.py +0 -0
  457. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/remote/test_detect_spool.py +0 -0
  458. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/remote/test_detect_upload_contract.py +0 -0
  459. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/remote/test_detect_wire_payload.py +0 -0
  460. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/remote/test_no_local_path_survives_redaction.py +0 -0
  461. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/remote/test_payload.py +0 -0
  462. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/remote/test_policy.py +0 -0
  463. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/remote/test_policy_service.py +0 -0
  464. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/remote/test_policy_service_cli.py +0 -0
  465. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/remote/test_redact_payload.py +0 -0
  466. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/remote/test_sync.py +0 -0
  467. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/remote/test_sync_detect.py +0 -0
  468. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/remote/test_upload_contract.py +0 -0
  469. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/telemetry/__init__.py +0 -0
  470. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/telemetry/test_activity_log.py +0 -0
  471. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/telemetry/test_cli.py +0 -0
  472. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/telemetry/test_events.py +0 -0
  473. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/telemetry/test_every_internal_save_is_reported.py +0 -0
  474. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/telemetry/test_release_gate.py +0 -0
  475. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/telemetry/test_state.py +0 -0
  476. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/telemetry/test_uploader.py +0 -0
  477. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_adr_cross_references_are_reciprocal.py +0 -0
  478. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_agent_instance_id.py +0 -0
  479. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_analysis.py +0 -0
  480. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_bom_shape.py +0 -0
  481. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_build_commit.py +0 -0
  482. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_cli.py +0 -0
  483. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_composition.py +0 -0
  484. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_detection_components.py +0 -0
  485. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_detection_event_time.py +0 -0
  486. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_detector_analyzer_contract.py +0 -0
  487. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_detector_analyzer_live.py +0 -0
  488. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_detector_blocked.py +0 -0
  489. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_detector_cache.py +0 -0
  490. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_detector_deterministic.py +0 -0
  491. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_detector_end_to_end.py +0 -0
  492. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_detector_finding.py +0 -0
  493. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_detector_history.py +0 -0
  494. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_detector_infra_reasoning.py +0 -0
  495. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_detector_jev.py +0 -0
  496. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_detector_names_the_service.py +0 -0
  497. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_detector_new_deterministic.py +0 -0
  498. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_detector_prompts.py +0 -0
  499. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_detector_reasoning.py +0 -0
  500. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_detector_render.py +0 -0
  501. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_detector_run.py +0 -0
  502. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_detector_secrets.py +0 -0
  503. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_detector_verdict.py +0 -0
  504. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_detector_vulnerable_dep_invoked.py +0 -0
  505. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_detector_why_it_stopped.py +0 -0
  506. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_detector_windows.py +0 -0
  507. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_evidence_is_dated_not_numbered.py +0 -0
  508. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_help_sections.py +0 -0
  509. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_monitor_cli.py +0 -0
  510. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_no_live_document_states_the_old_stage_three_default.py +0 -0
  511. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_no_test_undoes_every_patch_at_once.py +0 -0
  512. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_option_arity_matches_the_binary.py +0 -0
  513. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_readme_examples_are_real_output.py +0 -0
  514. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_release_gate_coverage.py +0 -0
  515. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_release_readiness.py +0 -0
  516. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_seam_boundary.py +0 -0
  517. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_sessions_access.py +0 -0
  518. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_sessions_end_to_end.py +0 -0
  519. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_sessions_protocol_typing.py +0 -0
  520. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_sessions_protocols.py +0 -0
  521. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_sessions_render.py +0 -0
  522. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_shell_separators_match_the_shell.py +0 -0
  523. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_stored_verdicts_are_never_gated_on_reasoning.py +0 -0
  524. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_the_detector_spec_lists_the_shipped_catalogue.py +0 -0
  525. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_the_jev_spec_states_the_shipped_thresholds.py +0 -0
  526. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_the_locality_claim_is_qualified_everywhere.py +0 -0
  527. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_title_disclosure_invariant.py +0 -0
  528. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_untrusted_content_never_travels.py +0 -0
  529. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_verification_subcommands_match_the_binary.py +0 -0
  530. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_what_jev_is_told_is_what_was_disclosed.py +0 -0
  531. {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/webhook/test_cli.py +0 -0
@@ -0,0 +1,55 @@
1
+ # Live Bedrock test in the sandbox account. Run by hand from the Actions tab.
2
+ # Credentials come from GitHub's OIDC token, exchanged for a one-hour session
3
+ # on a role that can only call Bedrock and read the invocation-logs bucket
4
+ # (integrations/bedrock/tofu/ci.tf). No AWS key is stored anywhere.
5
+ name: bedrock-live
6
+
7
+ on:
8
+ workflow_dispatch:
9
+ inputs:
10
+ ref:
11
+ description: Branch, tag or SHA holding the test to run. Dispatch from main; this is what gets checked out.
12
+ required: false
13
+ default: main
14
+ model:
15
+ description: Inference profile ID. Empty picks a Claude Sonnet profile.
16
+ required: false
17
+ default: ""
18
+
19
+ permissions:
20
+ id-token: write
21
+ contents: read
22
+
23
+ jobs:
24
+ live:
25
+ runs-on: ubuntu-latest
26
+ # The role trusts only jobs in this environment.
27
+ environment: bedrock-sandbox
28
+ timeout-minutes: 30
29
+ steps:
30
+ # GitHub dispatches only workflows on the default branch, and only to
31
+ # other refs after a first run, so the test's ref is an input instead.
32
+ - uses: actions/checkout@v4
33
+ with:
34
+ ref: ${{ inputs.ref }}
35
+ - uses: astral-sh/setup-uv@v6
36
+ - uses: aws-actions/configure-aws-credentials@v4
37
+ with:
38
+ role-to-assume: ${{ vars.BEDROCK_ROLE_ARN }}
39
+ aws-region: ${{ vars.BEDROCK_REGION || 'us-east-1' }}
40
+ role-duration-seconds: 3600
41
+ - run: uv sync
42
+ - name: Call each Bedrock API, read the logs back, run the rules
43
+ run: >
44
+ uv run --with boto3 python integrations/bedrock/live_test.py
45
+ --bucket "${{ vars.BEDROCK_LOGS_BUCKET }}"
46
+ --region "${{ vars.BEDROCK_REGION || 'us-east-1' }}"
47
+ ${{ inputs.model && format('--model {0}', inputs.model) || '' }}
48
+ --out bedrock-live
49
+ # Synthetic traffic only: scripted calls and a fake token.
50
+ - uses: actions/upload-artifact@v4
51
+ if: always()
52
+ with:
53
+ name: bedrock-live
54
+ path: bedrock-live/
55
+ retention-days: 3
@@ -279,9 +279,10 @@ silently editing an accepted ADR breaks that contract.
279
279
  - Calibrate priority by impact and urgency:
280
280
  - P0: critical, broadly applicable failure requiring immediate action.
281
281
  - P1: serious defect that should be fixed before this change lands.
282
- - P2: normal-priority defect eligible for automatic fixing.
282
+ - P2: normal-priority defect.
283
283
  - P3: low-priority suggestion.
284
- Do not inflate priority to make a finding eligible for automatic fixing.
284
+ - Report only P0 and P1 findings. Do not post P2 or P3 findings, inline or
285
+ in the review summary. Do not inflate priority to get a finding reported.
285
286
  - On subsequent reviews, verify earlier fixes and inspect their effects on
286
287
  callers and dependencies. Older code within the PR remains reviewable.
287
288
  - When review history supports it, identify a finding as:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: stacktrace-cli
3
- Version: 0.9.0
3
+ Version: 0.10.0
4
4
  Summary: CLI for Stacktrace — Detection and Response platform for AI Agents.
5
5
  Project-URL: Homepage, https://stacktrace.ai
6
6
  Author-email: "Stacktrace AI, Inc" <founders@stacktrace.ai>
@@ -20,8 +20,8 @@ Classifier: Topic :: Security
20
20
  Requires-Python: >=3.11
21
21
  Requires-Dist: click>=8.1
22
22
  Requires-Dist: httpx<1.0.dev0,>=0.28.1
23
- Requires-Dist: openaca==0.8.0
24
- Requires-Dist: openaidr==0.4.0
23
+ Requires-Dist: openaca==0.10.1
24
+ Requires-Dist: openaidr==0.6.1
25
25
  Requires-Dist: posthog<8,>=7.0
26
26
  Description-Content-Type: text/markdown
27
27
 
@@ -51,7 +51,7 @@ Requires Python 3.11 or newer.
51
51
 
52
52
  ```console
53
53
  $ stacktrace --version
54
- stacktrace 0.9.0 (openaca 0.8.0)
54
+ stacktrace 0.10.0 (openaca 0.10.1)
55
55
  ```
56
56
 
57
57
  ## Quick start
@@ -178,6 +178,21 @@ so naming the vendor is your act rather than ours (ADR-0033). Without both,
178
178
  stage three is not asked. `detect --analyzer jev` alone reads back what such a
179
179
  run already paid for and commissions nothing (ADR-0035).
180
180
 
181
+ **With Fleet configured** (`stacktrace remote configure`), the daemon sends
182
+ its findings, and its token usage for the cost ledger: tokens per run,
183
+ session, model and minute, and per run the repository's name (`owner/repo`,
184
+ from its `origin` remote), the branch, the session's own title (never the
185
+ prompt) and the opaque id of the account the agent is signed into, Claude
186
+ Code's or Devin's. With each account go its display name (else the part of its
187
+ email before the `@`), its plan, and a key that groups one person's accounts:
188
+ a hash of the email and the Fleet organization, never the email itself. A
189
+ finding carries its session's account the same way. Prompts, tool arguments,
190
+ results and paths are not sent (ADR-0096, ADR-0104, ADR-0101, ADR-0112).
191
+
192
+ To learn who Devin is signed in as, `stacktrace` runs Devin's own `devin auth
193
+ status`, which asks Devin's server. It asks again only after Devin's sign-in
194
+ changes, or ten minutes after an ask that named no one (ADR-0110).
195
+
181
196
  `sessions` omits prompts, tool arguments and results unless you pass
182
197
  `--include-content`. `monitor` binds to loopback only, and refuses a
183
198
  non-loopback address rather than warning about it.
@@ -215,9 +230,10 @@ enables telemetry again under a new identity (ADR-0039, ADR-0090).
215
230
 
216
231
  Beta, and under active development.
217
232
 
218
- `sessions`, `detect` and `monitor` work end to end today. Session collection
219
- currently reads Claude Code transcripts; further agent kinds are in progress
220
- upstream in [OpenAIDR](https://github.com/open-agent-security/openaidr).
233
+ `sessions`, `detect` and `monitor` work end to end today, for Claude Code and
234
+ Devin sessions alike (Devin CLI and Devin Desktop's local agent). Session collection is
235
+ [OpenAIDR](https://github.com/open-agent-security/openaidr)'s, and further agent
236
+ kinds arrive with it. The daemon observes every kind it reads, sub-agents included.
221
237
 
222
238
  ## Built on
223
239
 
@@ -24,7 +24,7 @@ Requires Python 3.11 or newer.
24
24
 
25
25
  ```console
26
26
  $ stacktrace --version
27
- stacktrace 0.9.0 (openaca 0.8.0)
27
+ stacktrace 0.10.0 (openaca 0.10.1)
28
28
  ```
29
29
 
30
30
  ## Quick start
@@ -151,6 +151,21 @@ so naming the vendor is your act rather than ours (ADR-0033). Without both,
151
151
  stage three is not asked. `detect --analyzer jev` alone reads back what such a
152
152
  run already paid for and commissions nothing (ADR-0035).
153
153
 
154
+ **With Fleet configured** (`stacktrace remote configure`), the daemon sends
155
+ its findings, and its token usage for the cost ledger: tokens per run,
156
+ session, model and minute, and per run the repository's name (`owner/repo`,
157
+ from its `origin` remote), the branch, the session's own title (never the
158
+ prompt) and the opaque id of the account the agent is signed into, Claude
159
+ Code's or Devin's. With each account go its display name (else the part of its
160
+ email before the `@`), its plan, and a key that groups one person's accounts:
161
+ a hash of the email and the Fleet organization, never the email itself. A
162
+ finding carries its session's account the same way. Prompts, tool arguments,
163
+ results and paths are not sent (ADR-0096, ADR-0104, ADR-0101, ADR-0112).
164
+
165
+ To learn who Devin is signed in as, `stacktrace` runs Devin's own `devin auth
166
+ status`, which asks Devin's server. It asks again only after Devin's sign-in
167
+ changes, or ten minutes after an ask that named no one (ADR-0110).
168
+
154
169
  `sessions` omits prompts, tool arguments and results unless you pass
155
170
  `--include-content`. `monitor` binds to loopback only, and refuses a
156
171
  non-loopback address rather than warning about it.
@@ -188,9 +203,10 @@ enables telemetry again under a new identity (ADR-0039, ADR-0090).
188
203
 
189
204
  Beta, and under active development.
190
205
 
191
- `sessions`, `detect` and `monitor` work end to end today. Session collection
192
- currently reads Claude Code transcripts; further agent kinds are in progress
193
- upstream in [OpenAIDR](https://github.com/open-agent-security/openaidr).
206
+ `sessions`, `detect` and `monitor` work end to end today, for Claude Code and
207
+ Devin sessions alike (Devin CLI and Devin Desktop's local agent). Session collection is
208
+ [OpenAIDR](https://github.com/open-agent-security/openaidr)'s, and further agent
209
+ kinds arrive with it. The daemon observes every kind it reads, sub-agents included.
194
210
 
195
211
  ## Built on
196
212
 
@@ -5,7 +5,7 @@ status: accepted
5
5
  date: 2026-08-28
6
6
  supersedes: null
7
7
  superseded-by: null
8
- amended-by: 0011, 0027, 0031, 0039, 0064, 0084, 0086, 0096
8
+ amended-by: 0011, 0027, 0031, 0039, 0064, 0084, 0086, 0096, 0109
9
9
  ---
10
10
 
11
11
  ## Context
@@ -6,7 +6,7 @@ date: 2026-09-17
6
6
  supersedes: null
7
7
  superseded-by: null
8
8
  amends: 0006
9
- amended-by: 0032, 0036, 0037, 0038, 0039, 0045, 0046, 0066, 0072
9
+ amended-by: 0032, 0036, 0037, 0038, 0039, 0045, 0046, 0066, 0072, 0107, 0113
10
10
  ---
11
11
 
12
12
  ## Context
@@ -6,7 +6,7 @@ date: 2026-09-18
6
6
  supersedes: null
7
7
  superseded-by: null
8
8
  amends: 0031
9
- amended-by: 0038, 0045
9
+ amended-by: 0038, 0045, 0107
10
10
  ---
11
11
 
12
12
  ## Context
@@ -6,7 +6,7 @@ date: 2026-09-21
6
6
  supersedes: null
7
7
  superseded-by: null
8
8
  amends: 0031, 0037
9
- amended-by: 0045
9
+ amended-by: 0045, 0107
10
10
  ---
11
11
 
12
12
  ## Context
@@ -6,7 +6,7 @@ date: 2026-09-22
6
6
  supersedes: null
7
7
  superseded-by: null
8
8
  amends: 0031, 0037, 0038
9
- amended-by: 0056, 0058, 0066, 0072
9
+ amended-by: 0056, 0058, 0066, 0072, 0107
10
10
  ---
11
11
 
12
12
  ## Context
@@ -6,7 +6,7 @@ date: 2026-09-23
6
6
  supersedes: 0047
7
7
  superseded-by: null
8
8
  amends: 0057
9
- amended-by: null
9
+ amended-by: 0104
10
10
  ---
11
11
 
12
12
  ## Context
@@ -6,7 +6,7 @@ date: 2026-09-24
6
6
  supersedes: null
7
7
  superseded-by: null
8
8
  amends: null
9
- amended-by: 0078
9
+ amended-by: 0078, 0105
10
10
  ---
11
11
 
12
12
  ## Context
@@ -6,7 +6,7 @@ date: 2026-09-30
6
6
  supersedes: null
7
7
  superseded-by: null
8
8
  amends: 0065
9
- amended-by: null
9
+ amended-by: 0105
10
10
  ---
11
11
 
12
12
  ## Context
@@ -6,7 +6,7 @@ date: 2026-10-05
6
6
  supersedes: null
7
7
  superseded-by: null
8
8
  amends: null
9
- amended-by: null
9
+ amended-by: 0113
10
10
  ---
11
11
 
12
12
  ## Context
@@ -6,7 +6,7 @@ date: 2026-10-05
6
6
  supersedes: null
7
7
  superseded-by: null
8
8
  amends: null
9
- amended-by: 0099
9
+ amended-by: 0099, 0113, 0114
10
10
  ---
11
11
 
12
12
  ## Context
@@ -6,7 +6,7 @@ date: 2026-10-06
6
6
  supersedes: null
7
7
  superseded-by: null
8
8
  amends: 0006
9
- amended-by: null
9
+ amended-by: 0103, 0109, 0115, 0116
10
10
  ---
11
11
 
12
12
  ## Context
@@ -0,0 +1,111 @@
1
+ ---
2
+ id: 0101
3
+ title: A run is named in Fleet by its own title, its repo's name, its branch and the account seen running it
4
+ status: proposed
5
+ date: 2026-10-08
6
+ supersedes: null
7
+ superseded-by: null
8
+ amends: null
9
+ amended-by: 0109, 0110, 0112
10
+ ---
11
+
12
+ ## Context
13
+
14
+ [ADR-0096](0096-cost-usage-may-leave-as-token-totals-and-work-identifiers.md)
15
+ allows four names per run on the usage upload: repo, branch, title and the
16
+ Anthropic account. It says what each may not be: a path, a working directory,
17
+ a machine name, or a prompt. It does not say where each comes from, and the
18
+ code offers a wrong answer for three of them:
19
+
20
+ - **Repo.** The only repo the code has is `working_directory`, which the cost
21
+ cohort keys on. It is a path, and the monitor shows it as one.
22
+ - **Title.** The monitor labels a run with the title a person set, then the
23
+ one the client generated, then the opening request (`render._topic`). The
24
+ third is the prompt.
25
+ - **Account.** No transcript records who was signed in. `login_type` reads
26
+ `oauthAccount.billingType` from Claude Code's config, today's value, and the
27
+ baseline marks it `assumed` for history.
28
+
29
+ ## Decision
30
+
31
+ 1. **Title: the session's own, cleaned, never the prompt.** The main session's
32
+ `title`, else its `generated_title`. Control characters are removed,
33
+ whitespace collapsed, and the result capped at 80 characters. It is dropped
34
+ when, case and spacing aside, it appears in the opening request, or the
35
+ opening request appears in it. A run with no title of its own sends none.
36
+ 2. **Repo: a name, from the remote.** The `origin` remote of the git repository
37
+ holding the main session's working directory, as its last two path segments
38
+ (`owner/repo`), without `.git`, userinfo or host. With no `origin`, the
39
+ repository's top-level directory name. Outside a repository, none. Read by
40
+ the daemon from `.git/config`, never by running `git`.
41
+ 3. **Branch: as the session records it** (`git_branch`).
42
+ 4. **Account: an opaque id, read live, and only for work seen live.** The
43
+ daemon reads `oauthAccount.accountUuid` from the same config `login_type`
44
+ reads: stable per Anthropic account, it tells two people on a shared box
45
+ apart and names neither. A run takes the account signed in the first time
46
+ the daemon sees a response of it at or after the daemon's start, and keeps
47
+ it. A run whose responses all predate the start, including the 30-day
48
+ backfill, sends none.
49
+ 5. **Each name passes the gate or travels as null.** Repo, branch, title,
50
+ account and model are checked with `enforce_usage_upload_contract`'s string
51
+ rules before they are stored, so a branch that looks like a path never costs
52
+ a page.
53
+
54
+ The cost cohort keeps `working_directory`. It is local, and a cohort per
55
+ checkout is what Phase 1 measures.
56
+
57
+ ## Alternatives considered
58
+
59
+ - **The working directory's last component as the repo.** Rejected: outside a
60
+ repository it is often the home directory, so it names the user, and two
61
+ machines' checkouts of one repository get different names, which defeats
62
+ Fleet's "by repo" view.
63
+ - **Run `git remote get-url origin`.** Rejected: a subprocess per run per
64
+ pass, from a daemon that otherwise execs nothing, to read one line of a file.
65
+ - **The opening request, shortened, when there is no title.** Rejected:
66
+ ADR-0096 clause 3. A shortened prompt is a prompt.
67
+ - **Drop a title only when it equals the prompt.** Rejected: a generated title
68
+ that copies the first words of the request carries them verbatim. Dropping
69
+ any title found inside the request loses some good titles, which is the safe
70
+ direction.
71
+ - **Assume today's account for history**, as the baseline's `login` does.
72
+ Rejected for the wire: the account is what names a person on a shared box,
73
+ and a guess names the wrong one. The baseline's mark is local and says
74
+ `assumed`.
75
+ - **The account's email.** Rejected: it names the person directly, and
76
+ personal data that need not leave the machine does not. Unique and readable
77
+ per person is exactly what makes an identifier name someone, so no readable
78
+ field of `oauthAccount` is a safe alternative.
79
+ - **The account's display name, or the local username.** Rejected: both are
80
+ a person's name, neither is unique, and on a shared dev box or CI runner
81
+ the username is the same for everyone.
82
+ - **A hash of the UUID.** Not taken. It would stop anyone mapping the id to a
83
+ person, including an org that wants to. The UUID already names no one; only
84
+ someone with access to the org's Anthropic account can map it.
85
+
86
+ ## Consequences
87
+
88
+ - Fleet's "by repo" view joins checkouts across machines by their remote.
89
+ - Backfilled history is attributed to the Fleet key only. A shared box's past
90
+ 30 days cannot be split by person.
91
+ - Fleet shows the account as a readable label derived from the UUID, such as
92
+ `account brave-otter-7f3a`, keyed by the UUID so two accounts never merge.
93
+ An org that wants names attaches one to an account inside Fleet. That is
94
+ Fleet's to build; nothing more travels for it.
95
+ - The field name `accountUuid` is the one Claude Code writes: its
96
+ `oauthAccount` builder sets it beside `emailAddress` and `organizationUuid`
97
+ (checked against the shipped 2.1.294 binary on 2026-10-08). Claude Code
98
+ reads a legacy `.config.json` in its configuration directory before
99
+ `.claude.json`, and so does the daemon. A missing field reads as no account,
100
+ never as an error.
101
+ - A title is still the easiest place for conversation to leak (ADR-0096). Watch
102
+ generated titles that quote a file name or an error message.
103
+
104
+ ## When to revisit
105
+
106
+ - If Claude Code records the signed-in account in transcripts, read it there
107
+ and send it for history too.
108
+ - If an org asks for titles off, through Task 12's policy field, add the switch
109
+ then.
110
+ - If titles are found to carry conversation in practice, narrow clause 1 rather
111
+ than add a filter per case.
@@ -0,0 +1,55 @@
1
+ ---
2
+ id: 0102
3
+ title: Token use is never compared with a provider's usage API
4
+ status: accepted
5
+ date: 2026-10-08
6
+ supersedes: null
7
+ superseded-by: null
8
+ amends: null
9
+ amended-by: null
10
+ ---
11
+
12
+ ## Context
13
+
14
+ `cost-phase-2.md` listed a reconciliation: Fleet would compare each org's
15
+ daily token totals with the provider's usage API and show the share of
16
+ usage Stacktrace did not see. `cost.md` said Phase 2 would measure that
17
+ coverage gap this way, and its Phase 4 was done when each agent's recorded
18
+ tokens reconciled with the provider's counts. The spec left one question open:
19
+ whether to ask each org for an Anthropic admin key, which the usage API
20
+ needs. On 2026-10-08 the product owner answered it: drop the feature
21
+ completely, because Stacktrace doesn't do that.
22
+
23
+ ## Decision
24
+
25
+ Stacktrace never compares, reconciles or checks its token figures against a
26
+ provider's usage API, billing export or invoice, in the environment or in
27
+ Fleet. It never asks an org for a provider admin key. Every figure is what the
28
+ transcripts record (ADR-0099), and the gap between that and what the provider
29
+ saw is stated in words where it matters, never measured.
30
+
31
+ ## Alternatives considered
32
+
33
+ - **Reconcile daily totals with the Anthropic usage API, given an admin key.**
34
+ Rejected by the product owner. It would also make Fleet hold a credential
35
+ with organisation-wide reach on the provider's side, for a comparison the
36
+ product doesn't need.
37
+ - **Reconcile only for orgs that offer a key.** Rejected with it: the feature
38
+ is dropped, not made optional.
39
+ - **Compare against an uploaded billing export.** Rejected for the same
40
+ reason, and it brings money into a product measured in tokens (ADR-0099).
41
+
42
+ ## Consequences
43
+
44
+ - No provider credential is asked for or held, in either repo.
45
+ - Usage from machines without Stacktrace, or from other tools on the same
46
+ key, stays invisible, and nothing estimates how much there is. The specs say
47
+ so rather than promising a measurement.
48
+ - Plan 017's Task 6 is removed, and with it Fleet's daily comparison and
49
+ "unattributed share".
50
+ - Phase 4 is done when Codex and Cursor sessions are counted by the same
51
+ rules as Claude Code's, not when anyone's totals match a provider's.
52
+
53
+ ## When to revisit
54
+
55
+ If the product owner asks for a comparison with a provider's figures.
@@ -0,0 +1,91 @@
1
+ ---
2
+ id: 0103
3
+ title: A finished run may leave as its baseline numbers, for org-wide baselines
4
+ status: accepted
5
+ date: 2026-10-08
6
+ supersedes: null
7
+ superseded-by: null
8
+ amends: 0096
9
+ amended-by: 0114, 0115
10
+ ---
11
+
12
+ ## Context
13
+
14
+ Cost Phase 2 gives an environment with fewer than 20 similar sessions of its
15
+ own the org's baselines for the same repo, entrypoint and model, so its waste
16
+ rules work from day one (`cost-phase-2.md` §2, plan 017 Task 12). Fleet can
17
+ build those only from the figures each environment's baseline is made of: per
18
+ finished run, its tokens by active minute, its burn and its behaviour measures
19
+ (ADR-0093). [ADR-0096](0096-cost-usage-may-leave-as-token-totals-and-work-identifiers.md)
20
+ closes what the usage upload may carry to token totals and a short list of work
21
+ identifiers, so none of these may leave today. The product owner asked for the
22
+ amendment on 2026-10-08, on one condition: aggregate numbers only, never any of
23
+ the trace itself.
24
+
25
+ ## Decision
26
+
27
+ This amends ADR-0096 clause 2 for the cost usage upload alone. Clauses 1 and 3,
28
+ and the rest of ADR-0006, stay in force.
29
+
30
+ 1. **Per finished run, its baseline numbers.** For each run the environment's
31
+ baseline holds (ADR-0093), and only once it has finished, the upload may
32
+ carry these and nothing else:
33
+ - `tokens`: recorded tokens, the run's total;
34
+ - `curve`: cumulative recorded tokens at the end of each active minute, at
35
+ most 240 values;
36
+ - `burn`: recorded tokens in the 5 minutes ending at each active minute, at
37
+ most 240 values;
38
+ - `subagents_in_10m`: the most sub-agents started within 10 minutes;
39
+ - `repeats`: how many times the most repeated call returned an unchanged
40
+ result, as a count;
41
+ - `input_per_response`: the 90th percentile of tokens sent per call;
42
+ - `lowest_cache_share`: the lowest cache-read share over 5 calls in a row on
43
+ a large context, or null;
44
+ - `cache_rewrites`: how many times the cache was rewritten on a large
45
+ context;
46
+ - the run's cohort: its repo as ADR-0101 names it (`owner/repo` or a
47
+ directory name, never a path), its entrypoint, and the model that carried
48
+ most of its tokens;
49
+ - the time of its last response, and a revision.
50
+ 2. **Numbers, never trace.** Each figure is a count, a token total or a ratio
51
+ the environment computes from the transcript. No call, tool name, argument,
52
+ result, file name, prompt, title or message travels with it, and none can be
53
+ recovered from it: `repeats` says how often, never what repeated. The
54
+ baseline's day slots (tokens by quarter hour of the day) stay on the
55
+ machine.
56
+ 3. **Back from Fleet, percentiles only.** Fleet returns, beside the policy
57
+ document, each cohort's percentiles over the org's last 30 days (p5, p50,
58
+ p95, p99 of each measure, and p50, p95, p99 of the curve and the burn at
59
+ each active minute) for cohorts with at least 20 runs. Never a run's own
60
+ figures, and never who ran it.
61
+ 4. **Runs a cost finding was raised on stay home.** They leave the local
62
+ baseline (ADR-0093), so they are not sent for the org's either.
63
+
64
+ ## Alternatives considered
65
+
66
+ - **Send the day slots too, for an org day curve.** Rejected: they say when a
67
+ person works, the day curve is `personal-anomaly`'s, and Fleet already has
68
+ each owner's day from the token buckets.
69
+ - **Send which call repeated, or the tools a run used.** Rejected: that is the
70
+ trace. The rules need how often, not what.
71
+ - **Compute the org's percentiles from the token buckets alone.** Rejected:
72
+ buckets carry tokens per minute, not the behaviour measures the waste rules
73
+ judge (sub-agents, repeats, input per call, the cache).
74
+ - **Ship each environment's own percentiles and merge them in Fleet.**
75
+ Rejected: percentiles do not merge, and an environment below 20 runs, the
76
+ case this exists for, has none.
77
+
78
+ ## Consequences
79
+
80
+ - `usage-upload.md` declares `run_figures`, and `enforce_usage_upload_contract`
81
+ refuses any key or string beyond it. A test walks the declared shape and
82
+ fails on any field that is not a number, other than the cohort names, the run
83
+ id and the time.
84
+ - An environment's evidence says "the org's runs" when an org cohort judged it,
85
+ never "this developer's".
86
+ - Fleet holds 30 days of per-run numbers per org.
87
+
88
+ ## When to revisit
89
+
90
+ If any figure is found to carry content, or a new waste rule needs a measure
91
+ not listed here: amend clause 1, never widen it by implication.
@@ -0,0 +1,92 @@
1
+ ---
2
+ id: 0104
3
+ title: Usage is its own upload, with its own job, its own gate and the store as its backlog
4
+ status: proposed
5
+ date: 2026-10-08
6
+ supersedes: null
7
+ superseded-by: null
8
+ amends: 0061
9
+ amended-by: null
10
+ ---
11
+
12
+ ## Context
13
+
14
+ Cost Phase 2 needs every environment's tokens in Fleet (`cost-phase-2.md` §1).
15
+ [ADR-0096](0096-cost-usage-may-leave-as-token-totals-and-work-identifiers.md)
16
+ decides what may leave: token totals per run, session, model and minute, and a
17
+ closed set of names per run. It does not decide how.
18
+
19
+ Three things already in the code push on that:
20
+
21
+ - ADR-0061 made the findings drain send findings and unknowns, nothing else,
22
+ and stopped the daemon capturing counters at all, because nothing read them.
23
+ - The detect-run gate (`enforce_detect_upload_contract`) declares one document's
24
+ shape and refuses every key outside it. It cannot pass a usage document, and
25
+ should not learn to.
26
+ - The findings queue is append-only and drained by a `seq` cursor (ADR-0046). A
27
+ usage bucket is not an event: it changes in place as a response grows
28
+ (OpenAIDR ADR-0014), so a cursor over it needs an append per change.
29
+
30
+ ## Decision
31
+
32
+ 1. **A new endpoint**, `POST /api/v1/usage`, one request per agent kind, in the
33
+ shape [`usage-upload.md`](../specs/usage-upload.md) declares. `detect-runs`
34
+ is unchanged.
35
+ 2. **A new job**, on its own thread, beside the findings drain and the BOM job.
36
+ It shares only the asset-transition lock with them (both can re-register an
37
+ asset). It is woken by the cost pass when a bucket changes, at most every
38
+ 10 s, and runs every 60 s as a heartbeat otherwise.
39
+ 3. **The daemon captures counters again, for this reader.** This amends
40
+ ADR-0061 clause 2, which stopped capture because nothing read it. Token
41
+ usage is a different counter with a reader, kept in its own tables
42
+ (`usage_buckets`, `usage_runs`, `usage_state`), additive under ADR-0057.
43
+ Clause 1 stands: the drain sends findings only.
44
+ 4. **The store is the backlog.** Each row keeps its revision and the revision
45
+ Fleet last accepted. A row whose two differ is pending. Buckets merge by
46
+ max, so every writer commutes and a count never falls.
47
+ 5. **Its own gate**, `enforce_usage_upload_contract`, built from the same walk
48
+ and the same three refusals as the detect-run gate: an undeclared key, a
49
+ rooted path or a URI naming a place, a credential. The producer checks each
50
+ name before the gate and sends `null` for one that would be refused.
51
+ 6. **No bisection and no parking.** A 422 holds every row and is reported.
52
+ Usage carries counts and names checked locally, so a refusal is a wire
53
+ mismatch, and splitting a page cannot isolate one.
54
+
55
+ ## Alternatives considered
56
+
57
+ - **Put usage on the findings drain.** Rejected, as ADR-0096 already rejected
58
+ it: ADR-0061 keeps the detection document one shape, and a usage backlog
59
+ would hold findings behind it.
60
+ - **A `seq` cursor over an append-only usage log.** Rejected: every rewrite of a
61
+ growing response appends a row, and the reader must collapse them to the
62
+ latest per key before it sends. A revision per row is the collapsed form.
63
+ - **Replace on write.** Rejected: the backfill thread and the pass both write,
64
+ and an older read landing last would lower a bucket Fleet already holds at a
65
+ higher count, at a higher revision Fleet would then keep.
66
+ - **Widen `_DETECT_RUN_SHAPE` to cover both documents.** Rejected: a declared
67
+ shape is what makes "a key it does not name is refused" mean something. One
68
+ shape for two documents lets a usage field ride on a detect run.
69
+ - **Reuse the drain's bisection.** Rejected: it exists to isolate one bad
70
+ finding among good ones. Usage has no row-shaped failure the producer can
71
+ reach, and bisecting a wire mismatch spends log₂(n) requests to refuse them
72
+ all.
73
+ - **Send usage through `remote sync`, daemon-less.** Not built. A cron cannot
74
+ keep a 10-second cadence or a heartbeat, and the backlog needs the store.
75
+
76
+ ## Consequences
77
+
78
+ - Fleet's Task 3 implements the endpoint against `usage-upload.md`. Until it
79
+ ships, a configured machine meets a 404, re-registers once, and backs off for
80
+ an hour. `personal-anomaly` keeps running, since its retirement waits for an
81
+ accepted request.
82
+ - A row Fleet refuses holds the backlog until the cause is fixed. `daemon
83
+ status` names it.
84
+ - The store grows by one row per session, model and active minute, pruned at 7
85
+ days once sent and at 30 days regardless.
86
+ - A bucket that genuinely shrinks never says so. No case of one is known.
87
+
88
+ ## When to revisit
89
+
90
+ - If Fleet answers usage refusals per row, bisection becomes worth its code.
91
+ - If a second producer, such as a daemon-less posture, needs to send usage, the
92
+ backlog cannot stay in the daemon's store alone.